Release 980927 Sun Sep 27 14:25:38 1998 Petter Reinholdtsen <pere@td.org.uit.no> * [files/drive.c] Make sure GetDriveType32A() handles param NULL. Added some doc on function. Sun Sep 27 14:07:26 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk> * [controls/edit.c] [windows/win.c] Don't call SetWindowLong() in EDIT_WM_NCREATE. Fix SetWindowLong(GWL_[EX]STYLE) to work for 16bit windows. Remove UpdateWindow() call. Sun Sep 27 13:41:22 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [scheduler/*.c] [server/event.c] [server/mutex.c] [server/semaphore.c] Implemented server-side synchronisation objects. Sun Sep 27 01:13:35 1998 Alex Priem <alexp@sci.kun.nl> * [dlls/comctl32/treeview.c] [include/treeview.h] [include/comctl.h] Treeview implementation. * [dlls/comctl32/trackbar.c] [include/trackbar.h] Trackbar implementation. Sat Sep 26 20:49:13 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de> * [if1632/thunk.c] [tools/build.c] [win32/kernel32.c] Bugfix: several problems with flat thunks fixed. * [memory/selector.c] Bugfix: IsBad...Ptr16 didn't work for limit_in_pages segments. * [scheduler/thread.c] Bugfix: CreateThread: Allow id parameter == NULL. * [objects/gdiobj.c] Bugfix: IsGDIObject: Return correct object type for stock objects. * [msdos/dpmi.c] Bugfix: fixed typo in INT_DoRealModeInt. * [msdos/int21.c] Bugfix: int21 READ *must* use WIN16_hread, not _hread16. * [if1632/kernel.spec] [if1632/dummy.c] [if1632/thunk.c] [loader/ne/module.c] [scheduler/event.c] [scheduler/synchro.c] [scheduler/thread.c] [win32/kernel32.c] [win32/ordinals.c] Added names/stubs for all undocumented KERNEL routines (Win95). Added the following undoc. 16-bit equivalents to Win32 routines: KERNEL.441-443,449-453,456-462,471-476,479-486,488. Added stubs for some other KERNEL routines. * [memory/heap.c] [memory/global.c] [include/global.h] Implemented Local32... 32-bit local heap routines (KERNEL.208-215, 229). * [miscemu/instr.c] [loader/module.c] [include/module.h] Implemented __GP fault handling and HasGPHandler (KERNEL.338). * [misc/error.c] Implemented LogParamErrorRegs (KERNEL.327). * [loader/task.c] [include/windows.h] Implemented GetCodeInfo (KERNEL.104). * [loader/task.c] [scheduler/thread.c] [include/thread.h] Implemented [GS]etThreadQueue and [GS]etFastQueue (KERNEL.463/4, 624/5). * [if1632/gdi.spec] [objects/dc.c] [objects/dib.c] [objects/bitmap.c] [include/windows.h] Bugfix: fixed wrong parameter for CreateDIBSection16. Added [GS]etDIBColorTable16, stub for GetBoundsRect16. Partially implemented BITMAP_GetObject16 for DIBs. * [if1632/gdi.spec] [relay32/gdi32.spec] [objects/palette.c] Added some GDI stubs. * [if1632/Makefile.in] [if1632/display.spec] [if1632/mouse.spec] [if1632/keyboard.spec] [if1632/builtin.c] [windows/keyboard.c] Added some stubs for Win16 drivers: KEYBOARD, MOUSE, DISPLAY. * [if1632/wprocs.spec] [msdos/vxd.c] Added some stubs for VxDs: VMM, ConfigMG, TimerAPI. * [msdos/int2f.c] Added some stubs for real-mode network drivers. Sat Sep 26 18:18:18 1998 Marcus Meissner <marcus@jet.franken.de> * [configure.in] Merged in some more of the FreeBSD ports/emulators/wine patches. (Maintainer(s) of this port: You can just submit these patches to Alexandre directly.) * [loader/pe_image.c] Check filesize of image against size derived from header to spot truncated executeables without crashing. * [files/directory.c] Set envvar "COMSPEC". One win32(!!) program crashes without it. * [multimedia/mmio.c] Added mmioSetInfo32. * [include/file.h] Return STD_ERROR_HANDLE for AUX and PRT dos handles. * [loader/module.c] Handle executeables with spaces in their names a bit better in CreateProcess. * [relay32/msvfw32.spec][if1632/msvideo.spec][multimedia/msvideo.c][include/vfw.h] Started on MS Video support (can load Win32 ICMs). * [tools/testrun] A bit smarter use of ps. * [memory/virtual.c] Report PAGE_GUARDed pages as PAGE_PROTECTED (AutoCAD LT R17 fails without that check (since Win95 doesn't know about PAGE_GUARD)). Sat Sep 26 15:04:05 1998 Ove Kaaven <ovek@arcticnet.no> * [include/miscemu.h] [if1632/builtin.c] [loader/task.c] [miscemu/instr.c] [msdos/dpmi.c] [msdos/int21.c] [msdos/interrupts.c] [windows/user.c] INT_[S|G]etHandler was renamed to INT_[S|G]etPMHandler. Added handlers to deal with real-mode interrupts; DOS programs are now able to hook real-mode interrupts. * [loader/dos/module.c] [msdos/dosmem.c] [msdos/int21.c] Moved real-mode interrupt table initialization to msdos/dosmem.c, and made new V86 tasks get a full copy of the existing "system memory" instead of almost empty space. Misc fixes. * [include/dosexe.h] [loader/dos/module.c] [msdos/dpmi.c] [msdos/int2f.c] First shot at letting DOS programs start up DPMI (but DPMI is still disabled for DOS programs, for pkunzip's sake). * [include/debugger.h] [debugger/break.c] [debugger/dbg.y] [debugger/registers.c] [debugger/memory.c] [debugger/info.c] [loader/dos/dosvm.c] First shot at making Wine's debugger work for DOS programs. The -debug flag works, as do "nexti" and "stepi". Sat Sep 26 13:13:13 1998 Juergen Schmied <juergen.schmied@metronet.de> * [dlls/shell32/dataobject.c] New classes IEnumFORMATETC implemented, IDataObject stubs. * [dlls/shell32/*.*][relay32/shell32.spec] Bugfixes. New: ICM_InsertItem(), ILCreateFromPath(). Implemented: ILCloneFirst(). Stubs: ILIsEqual(), ILFindChild(), SHLogILFromFSIL(), PathMatchSpec(), PathIsExe(). Changed: ILGetSize(), _ILIsDesktop(), PathCombine(). * [include/shlobj.h] New SHLGUID's New structures: DVTARGETDEVICE32, STGMEDIUM32, FORMATETC32, CLIPFORMAT32. New interfaces: IEnumFORMATETC, IDataObject, ICommDlgBrowser IDockingWindowFrame, IServiceProvider. * [dlls/shell32/folders.c] Stubs for IShellLink. * [loader/resource.c] Small fixes. * [misc/crtdll.c][relay32/crtdll.spec] New __dllonexit(). * [windows/message.c] SendNotifyMessageA, SendMessageCallBack32A half implemented. * [controls/edit.c] EDIT_WM_SetText set EF_UPDATE flag not for ES_MULTILINE. * [files/file.c] Handling of fileposition fixed. Fri Sep 25 18:13:30 1998 Patrik Stridvall <ps@leissner.se> * [include/windows.h] [include/wintypes.h] [ole/ole2nls.h] [relay32/kernel32.spec] Implemented EnumDateFormats and EnumTimeFormats. Only adds US English support. * [Makefile.in] [configure.in] [dlls/Makefile.in] [dlls/psapi/Makefile.in] [dlls/psapi/psapi_main.c] New files to implement stubs for PSAPI.DLL (NT only). * [relay32/Makefile.in] [relay32/builtin32.c] [relay32/psapi.spec] New spec file for PSAPI.DLL (NT only). * [scheduler/handle.c] HANDLE_GetObjPtr should only interpret the pseudo handles as the current thread or the current process if a thread or a process is requested. * [include/winversion.h] [misc/version.c] Adds the global function VERSION_GetVersion() so functions can have different behavior depending on the -winver flag. * [include/oledlg.h] [ole/oledlg.c] Minor fixes. * [windows/winproc.c] Minor changes. * [include/imm.h] [misc/imm.c] Now returns correct values under both Windows 95 and NT 4.0. Thu Sep 24 22:11:44 1998 Kristian Nielsen <kristian.nielsen@risoe.dk> * [configure.in] [include/acconfig.h] [include/thread.h] [scheduler/sysdeps.c] Autoconfig test for non-reentrant libc. Wed Sep 23 19:52:12 1998 Matthew Becker <mbecker@glasscity.net> * [*/*.c] Miscellaneous documentation updates and debugging output standardizations. * [objects/clipping.c] Added ExtSelectClipRgn. Wed Sep 23 00:03:28 EDT 1998 Pete Ratzlaff <pratzlaff@cfa.harvard.edu> * [include/windows.h] [if1632/user.spec] [relay32/user32.spec] [windows/keyboard.c] Added, marginally implemented, GetKeyboardLayoutName(). Only returns US English keyboard name. Tue Sep 22 16:32:41 1998 Marcel Baur <mbaur@iiic.ethz.ch> * [programs/control/*] New Winelib application. Mon Sep 21 00:29:18 1998 Peter Hunnisett <hunnise@nortel.ca> * [include/dplay.h][multimedia/dplay.c][ole/compobj.c] Added all DirectPlayLobby interfaces and enhanced DirectPlay and DirectPlayLobby support. Still not all that much. Useful enough if you just need to start a program, don't try any real dplay/lobby stuff. * [documentation/status/directplay] Added a very little bit. * [graphics/ddraw.c] - Call to SetWindowLong32A wasn't working because there was no memory set aside when the window class was registered. - Fixed some xlib reference counting and change the behaviour of DirectDrawSurface3_SetPalette to mimic observed behaviour (palette is associated will all backbuffers) - Also stored all palette colour fields and spit back our saved colour fields rather than query X for them. - Added plenty of AddRef and Release traces. - Added Xlib support for using -desktop option. - Fixed Xlib message handling. Messages weren't being passed to the application. Fixes mouse movements in some xlib DDraw games. - Added a few stubs. * [windows/win.c][include/winerror.h] Fixed up some error handling in WIN_SetWindowLong. SetLastError wasn't being used. Could cause problems with 0 return codes. Added new error in winerror (1400). * [AUTHORS] [include/authors.h] Added myself as a Wine author. Sun Sep 20 21:22:44 1998 Alexander Larsson <alla@lysator.liu.se> * [loader/module.c] Changed GetModuleFileName32A so that is returns the long version of the filename. Note that just the name is long, not the directories. Sat Sep 19 20:05:30 1998 Per Ångström <pang@mind.nu> * [controls/menu.c] Made a couple of fixes to make life easier for applications that alter their menus at runtime. * [windows/defdlg.c] Removed the cast of the return value from dialog procedures to a 16-bit bool. The return value needs to retain all its 32 bits, since it is not always a bool, such as when responding to the WM_NCHITTEST message. Fri Sep 18 11:30:38 1998 Sergey Turchanov <turchanov@usa.net> * [loader/resource.c] Fixed very funny bug (though gravely affecting further excecution) with FindResource[Ex]32 functions. * [include/multimon.h] [windows/multimon.c] [relay32/user32.spec] [include/windows.h] [windows/sysmetrics.c] Default implementation for Multimonitor API. * [include/windows.h] [windows/winpos.c] Fixed incorrect declaration (and behaviour) of GetWindowRect32. Wed Sep 16 10:21:15 1998 Gerard Patel <G.Patel@Wanadoo.fr> * [controls/edit.c] Fixed EDIT_EM_GetLine to use correctly length of lines. Tue Sep 15 20:40:16 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de> * [misc/tweak.c][include/tweak.h][controls/menu.c] Replaced the tweak graphic routines by calls to DrawEdge32(). * [misc/tweak.c][include/tweak.h][documentation/win95look] [wine.ini][*/*] Changed "look and feel" selection. Allows Win3.1, Win95 and Win98 (no GUI code implemented) look and feel. * [dlls/comctl32/header.c][include/header.h][include/commctrl.h] Started callback item support and did some minor improvements. * [dlls/comctl32/imagelist.c] Fixed bug in transparent image display. ImageList_GetIcon is still buggy :-( * [dlls/comctl32/toolbar.c] Fixed button drawing (partial hack). * [dlls/comctl32/commctrl.c] Fixed MenuHelp(). * [controls/button.c] Added 3d effect for groupbox. * [windows/msgbox.c] Added font support for message boxes. * [windows/nonclient.c] Fixed window moving bug. * [dlls/comctl32/*.c] Various improvements. * [dlls/comctl32/listview.c][dlls/comctl32/rebar.c] [include/commctrl.h] More messages. * [windows/syscolor.c][include/windows.h] Introduced new Win98 system colors. Tue Sep 15 18:29:45 1998 Wesley Filardo <eightknots@aol.com> * [files/profile.c] Added support in PROFILE_LoadWineIni for -config option * [misc/main.c] [include/options.h] Added -config option. Tue Sep 15 18:22:26 1998 Petter Reinholdtsen <pere@td.org.uit.no> * [documentation/Makefile.in] Make sure directory exists before installing into it. Tue Sep 15 01:47:33 1998 Pablo Saratxaga <pablo.sarachaga@ping.be> * [ole/nls/*] [ole/ole2nls.c] [include/winnls.h] Fixed a few errors and completed some NLS files. Mon Sep 14 01:23:45 1998 Joseph Pranevich <knight@baltimore.wwaves.com> * [include/miscemu.h] [msdos/interrupts.c] Removed a compilation warning, added INT 25 to the list of interrupts callable from DOS applications, added a debug message when unsupported interrupts are used. Sun Sep 13 19:55:22 1998 Lawson Whitney <lawson_whitney@juno.com> * [if1632/relay.c] CallProcEx32W should not reverse arguments. Sun Aug 17 21:18:12 1998 Eric Pouech <eric.pouech@lemel.fr> * [multimedia/midi.c] [multimedia/init.c] [multimedia/mmsys.c] [include/multimedia.h] [include/mmsystem.h] [multimedia/Makefile.in] [multimedia/midipatch.c] [if1632/multimedia.spec] Made MIDI input and output functional on OSS capable systems. * [multimedia/timer.c] Changes to trigger callbacks at the accurate pace even when fake timers are used.
diff --git a/dlls/comctl32/animate.c b/dlls/comctl32/animate.c index 9303711..9c2fc19 100644 --- a/dlls/comctl32/animate.c +++ b/dlls/comctl32/animate.c
@@ -14,6 +14,8 @@ */ #include "windows.h" +#include "winnt.h" +#include "winbase.h" #include "commctrl.h" #include "animate.h" #include "win.h" @@ -23,34 +25,136 @@ #define ANIMATE_GetInfoPtr(wndPtr) ((ANIMATE_INFO *)wndPtr->wExtra[0]) +static BOOL32 +ANIMATE_LoadRes32A (ANIMATE_INFO *infoPtr, HINSTANCE32 hInst, LPSTR lpName) +{ + HRSRC32 hrsrc; + HGLOBAL32 handle; + + hrsrc = FindResource32A (hInst, lpName, "AVI"); + if (!hrsrc) + return FALSE; + + handle = LoadResource32 (hInst, hrsrc); + if (!handle) + return FALSE; + + infoPtr->lpAvi = LockResource32 (handle); + if (!infoPtr->lpAvi) + return FALSE; + + return TRUE; +} + + +static BOOL32 +ANIMATE_LoadFile32A (ANIMATE_INFO *infoPtr, LPSTR lpName) +{ + HANDLE32 handle; + + infoPtr->hFile = + CreateFile32A (lpName, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); + if (!infoPtr->hFile) + return FALSE; + + handle = + CreateFileMapping32A (infoPtr->hFile, NULL, PAGE_READONLY | SEC_COMMIT, + 0, 0, NULL); + if (!handle) { + CloseHandle (infoPtr->hFile); + infoPtr->hFile = 0; + return FALSE; + } + + infoPtr->lpAvi = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, 0); + if (!infoPtr->lpAvi) { + CloseHandle (infoPtr->hFile); + infoPtr->hFile = 0; + return FALSE; + } + + return TRUE; +} + + +static VOID +ANIMATE_Free (ANIMATE_INFO *infoPtr) +{ + if (infoPtr->hFile) { + UnmapViewOfFile (infoPtr->lpAvi); + CloseHandle (infoPtr->hFile); + infoPtr->lpAvi = NULL; + } + else { + GlobalFree32 (infoPtr->lpAvi); + infoPtr->lpAvi = NULL; + } +} + + +static VOID +ANIMATE_GetAviInfo (infoPtr) +{ + + +} + + static LRESULT ANIMATE_Open32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr); + HINSTANCE32 hInstance = (HINSTANCE32)wParam; + + ANIMATE_Free (infoPtr); if (!lParam) { - - FIXME (animate, "close avi: empty stub!\n"); - + TRACE (animate, "closing avi!\n"); return TRUE; } if (HIWORD(lParam)) { - FIXME (animate, "(\"%s\") empty stub!\n", (LPSTR)lParam); + if (ANIMATE_LoadRes32A (infoPtr, hInstance, (LPSTR)lParam)) { + + FIXME (animate, "AVI resource found!\n"); + + } + else { + FIXME (animate, "No AVI resource found!\n"); + if (ANIMATE_LoadFile32A (infoPtr, (LPSTR)lParam)) { + FIXME (animate, "AVI file found!\n"); + } + else { + FIXME (animate, "No AVI file found!\n"); + return FALSE; + } + } } else { - FIXME (animate, "(%u) empty stub!\n", (WORD)LOWORD(lParam)); + if (ANIMATE_LoadRes32A (infoPtr, hInstance, + MAKEINTRESOURCE32A((INT32)lParam))) { + FIXME (animate, "AVI resource found!\n"); + } + else { + FIXME (animate, "No AVI resource found!\n"); + return FALSE; + } } + ANIMATE_GetAviInfo (infoPtr); return TRUE; } +// << ANIMATE_Open32W >> + + static LRESULT ANIMATE_Play (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { @@ -131,7 +235,8 @@ ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr); - + /* free avi data */ + ANIMATE_Free (infoPtr); /* free animate info data */ COMCTL32_Free (infoPtr);
diff --git a/dlls/comctl32/comctl32undoc.c b/dlls/comctl32/comctl32undoc.c index e45f77f..430dd67 100644 --- a/dlls/comctl32/comctl32undoc.c +++ b/dlls/comctl32/comctl32undoc.c
@@ -10,7 +10,8 @@ * COMCTL32.DLL (internally). * * TODO - * - Write documentation. + * - Add more functions. + * - Write some documentation. */ #include <string.h> @@ -27,6 +28,22 @@ /************************************************************************** + * COMCTL32_11 [COMCTL32.11] + */ + +DWORD WINAPI +COMCTL32_11 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, + DWORD dwParam4, DWORD dwParam5, DWORD dwParam6) +{ + + FIXME (commctrl, "(%08lx, %08lx, %08lx, %08lx, %08lx, %08lx): empty stub\n", + dwParam1, dwParam2, dwParam3, dwParam4, dwParam5, dwParam6); + + return 0; +} + + +/************************************************************************** * Alloc [COMCTL32.71] * * Allocates memory block from the dll's local heap @@ -153,6 +170,25 @@ /************************************************************************** + * The MRU-API is a set of functions to manipulate MRU(Most Recently Used) + * lists. + * + * + */ + +typedef struct tagMRUINFO +{ + DWORD dwParam1; + DWORD dwParam2; + DWORD dwParam3; + HKEY hkeyMain; + LPCSTR lpszSubKey; + DWORD dwParam6; +} MRUINFO, *LPMRUINFO; + + + +/************************************************************************** * CreateMRUListA [COMCTL32.151] * * PARAMS @@ -161,54 +197,233 @@ * RETURNS */ -DWORD WINAPI -CreateMRUList32A (DWORD dwParam) +LPVOID WINAPI +CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2, + DWORD dwParam3, DWORD dwParam4); + +LPVOID WINAPI +CreateMRUList32A (LPMRUINFO lpmi) { - - FIXME (commctrl, "(%lx)\n", dwParam); - - return 1; + return CreateMRUListEx32A (lpmi, 0, 0, 0); } +DWORD WINAPI +FreeMRUList32A (LPVOID ptr) +{ + FIXME (commctrl, "(%p) empty stub!\n", ptr); + + COMCTL32_Free (ptr); + + return TRUE; +} + + + + + + +LPVOID WINAPI +CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) +{ + DWORD dwLocal1; + HKEY hkeyResult; + DWORD dwLocal3; + LPVOID lMRU; + DWORD dwLocal5; + DWORD dwLocal6; + DWORD dwLocal7; + DWORD dwDisposition; + + /* internal variables */ + LPVOID ptr; + + FIXME (commctrl, "(%p) empty stub!\n", lpmi); + + if (lpmi) { + FIXME (commctrl, "(%lx %lx %lx %lx \"%s\" %lx)\n", + lpmi->dwParam1, lpmi->dwParam2, lpmi->dwParam3, + lpmi->hkeyMain, lpmi->lpszSubKey, lpmi->dwParam6); + } + + /* dummy pointer creation */ + ptr = COMCTL32_Alloc (32); + + FIXME (commctrl, "-- ret = %p\n", ptr); + + return ptr; +} + + + +DWORD WINAPI +AddMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + + FIXME (commctrl, "(%lx %lx %lx) empty stub!\n", + dwParam1, dwParam2, dwParam3); + + return 0; +} + + +DWORD WINAPI +FindMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) +{ + + FIXME (commctrl, "(%lx %lx %lx %lx) empty stub!\n", + dwParam1, dwParam2, dwParam3, dwParam4); + + return -1; +} + + + +/************************************************************************** + * Str_GetPtrA [COMCTL32.233] + * + * PARAMS + * lpSrc [I] + * lpDest [O] + * nMaxLen [I] + * + * RETURNS + */ + +INT32 WINAPI +Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen) +{ + INT32 len; + + TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen); + + if (!lpDest && lpSrc) + return lstrlen32A (lpSrc); + + if (nMaxLen == 0) + return 0; + + if (lpSrc == NULL) { + lpDest[0] = '\0'; + return 0; + } + + len = lstrlen32A (lpSrc); + if (len >= nMaxLen) + len = nMaxLen - 1; + + RtlMoveMemory (lpDest, lpSrc, len); + lpDest[len] = '\0'; + + return len; +} + /************************************************************************** * Str_SetPtrA [COMCTL32.234] * * PARAMS - * dwParam1 [I] - * dwParam2 [I] + * lppDest [O] + * lpSrc [I] * * RETURNS */ BOOL32 WINAPI -COMCTL32_Str_SetPtrA (LPSTR lpStr, LPVOID *lpPtr) +Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc) +{ + TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc); + + if (lpSrc) { + LPSTR ptr = COMCTL32_ReAlloc (lppDest, lstrlen32A (lpSrc) + 1); + if (!ptr) + return FALSE; + lstrcpy32A (ptr, lpSrc); + *lppDest = ptr; + } + else { + if (*lppDest) { + COMCTL32_Free (*lppDest); + *lppDest = NULL; + } + } + + return TRUE; +} + + +/************************************************************************** + * Str_GetPtrW [COMCTL32.235] + * + * PARAMS + * lpSrc [I] + * lpDest [O] + * nMaxLen [I] + * + * RETURNS + */ + +INT32 WINAPI +Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen) { INT32 len; - LPSTR ptr; - TRACE (commctrl, "(%p %p)\n", lpStr, lpPtr); + TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen); + + if (!lpDest && lpSrc) + return lstrlen32W (lpSrc); + + if (nMaxLen == 0) + return 0; + + if (lpSrc == NULL) { + lpDest[0] = L'\0'; + return 0; + } + + len = lstrlen32W (lpSrc); + if (len >= nMaxLen) + len = nMaxLen - 1; + + RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR)); + lpDest[len] = L'\0'; + + return len; +} + + +/************************************************************************** + * Str_SetPtrW [COMCTL32.236] + * + * PARAMS + * lpDest [O] + * lpSrc [I] + * + * RETURNS + */ + +BOOL32 WINAPI +Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc) +{ + TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc); - if (lpStr) { - len = lstrlen32A (lpStr); - ptr = COMCTL32_ReAlloc (lpPtr, len + 1); - if (!(ptr)) + if (lpSrc) { + INT32 len = lstrlen32W (lpSrc) + 1; + LPWSTR ptr = COMCTL32_ReAlloc (lppDest, len * sizeof(WCHAR)); + if (!ptr) return FALSE; - lstrcpy32A (ptr, lpStr); - if (!lpPtr) - return FALSE; - *lpPtr = ptr; - return TRUE; + lstrcpy32W (ptr, lpSrc); + *lppDest = ptr; + } + else { + if (*lppDest) { + COMCTL32_Free (*lppDest); + *lppDest = NULL; + } } - if (*lpPtr) { - COMCTL32_Free (*lpPtr); - return TRUE; - } - - return FALSE; + return TRUE; } @@ -636,7 +851,7 @@ BOOL32 WINAPI DPA_Grow (const HDPA hdpa, INT32 nGrow) { - FIXME (commctrl, "(%p %d) stub!\n", hdpa, nGrow); + TRACE (commctrl, "(%p %d)\n", hdpa, nGrow); if (!hdpa) return FALSE; @@ -676,7 +891,7 @@ if (!hdpa) return NULL; - FIXME (commctrl, "(%p %p) stub!\n", hdpa, hdpaNew); + TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew); if (!hdpaNew) { /* create a new DPA */ @@ -1019,7 +1234,7 @@ LPVOID t, v; INT32 i, j; - if (l > r) { + if (r > l) { v = lpPtrs[r]; i = l - 1; j = r; @@ -1064,7 +1279,9 @@ TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam); - DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1, pfnCompare, lParam); + if ((hdpa->nItemCount > 1) && (hdpa->ptrs)) + DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1, + pfnCompare, lParam); return TRUE; } @@ -1107,6 +1324,8 @@ INT32 l, r, x, n; LPVOID *lpPtr; + TRACE (commctrl, "binary search\n"); + l = (nStart == -1) ? 0 : nStart; r = hdpa->nItemCount - 1; lpPtr = hdpa->ptrs; @@ -1138,7 +1357,7 @@ LPVOID *lpPtr; INT32 nIndex; - FIXME (commctrl, "linear search\n"); + TRACE (commctrl, "linear search\n"); nIndex = (nStart == -1)? 0 : nStart; lpPtr = hdpa->ptrs; @@ -1267,3 +1486,63 @@ return atoi(lpString); } + +/************************************************************************** + * COMCTL32_385 [COMCTL32.385] + */ + +DWORD WINAPI +COMCTL32_385 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + + FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n", + dwParam1, dwParam2, dwParam3); + + return 0; +} + + +/************************************************************************** + * COMCTL32_386 [COMCTL32.386] + */ + +DWORD WINAPI +COMCTL32_386 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + + FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n", + dwParam1, dwParam2, dwParam3); + + return 0; +} + + +/************************************************************************** + * COMCTL32_387 [COMCTL32.387] + */ + +DWORD WINAPI +COMCTL32_387 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + + FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n", + dwParam1, dwParam2, dwParam3); + + return 0; +} + + +/************************************************************************** + * COMCTL32_388 [COMCTL32.388] + */ + +DWORD WINAPI +COMCTL32_388 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ + + FIXME (commctrl, "(%08lx, %08lx, %08lx): empty stub\n", + dwParam1, dwParam2, dwParam3); + + return 0; +} +
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 0c6f00e..b0b5c7c 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c
@@ -32,10 +32,13 @@ * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'. * * PARAMS - * hinstDLL [I] + * hinstDLL [I] handle to the 'dlls' instance * fdwReason [I] * lpvReserved [I] * + * RETURNS + * Success: TRUE + * Failure: FALSE */ BOOL32 WINAPI @@ -68,59 +71,64 @@ * MenuHelp [COMCTL32.2] * * PARAMS - * uMsg - * wParam - * lParam - * hMainMenu - * hInst - * hwndStatus - * lpwIDs + * uMsg [I] + * wParam [I] + * lParam [I] + * hMainMenu [I] handle to the applications main menu + * hInst [I] + * hwndStatus [I] handle to the status bar window + * lpwIDs [I] pointer to an array of intergers (see NOTES) * * RETURNS - * None + * No return value * * NOTES - * Some features are still missing because of incomplete WM_MENUSELECT - * messages (16->32 bit conversion). + * The official documentation is incomplete! */ VOID WINAPI MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu, HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs) { - char szStatusText[128]; + UINT32 uMenuID = 0; - if (!IsWindow32 (hwndStatus)) return; + if (!IsWindow32 (hwndStatus)) + return; switch (uMsg) { case WM_MENUSELECT: - TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n", - wParam, lParam); + TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n", + wParam, lParam); if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) { /* menu was closed */ + TRACE (commctrl, "menu was closed!\n"); SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0); } - else { - if (HIWORD(wParam) & MF_POPUP) { - FIXME (commctrl, "popup 0x%08x 0x%08lx\n", wParam, lParam); + else { + /* menu item was selected */ + if (HIWORD(wParam) & MF_POPUP) + uMenuID = (UINT32)*(lpwIDs+1); + else + uMenuID = (UINT32)LOWORD(wParam); + TRACE (commctrl, "uMenuID = %u\n", uMenuID); - szStatusText[0] = 0; - } - else { - TRACE (commctrl, "menu item selected!\n"); - if (!LoadString32A (hInst, LOWORD(wParam), szStatusText, 128)) - szStatusText[0] = 0; - } - SendMessage32A (hwndStatus, SB_SETTEXT32A, 255 | SBT_NOBORDERS, - (LPARAM)szStatusText); - SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0); - } - break; + if (uMenuID) { + CHAR szText[256]; - default: - WARN (commctrl, "Invalid Message!\n"); - break; + if (!LoadString32A (hInst, uMenuID, szText, 256)) + szText[0] = 0; + + SendMessage32A (hwndStatus, SB_SETTEXT32A, + 255 | SBT_NOBORDERS, (LPARAM)szText); + SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0); + } + } + break; + + default: + WARN (commctrl, "Invalid Message!\n"); + break; } } @@ -198,10 +206,10 @@ * lpInfo [I] pointer to an array of integers * * RETURNS - * None. + * No return value. * * NOTES - * + * The official documentation is incomplete! */ VOID WINAPI @@ -244,6 +252,9 @@ * lprc [I] pointer to a rectangle * text [I] pointer to the text * style [I] + * + * RETURNS + * No return value. */ VOID WINAPI @@ -281,6 +292,9 @@ * lprc [I] pointer to a rectangle * text [I] pointer to the text * style [I] + * + * RETURNS + * No return value. */ VOID WINAPI @@ -293,8 +307,19 @@ /*********************************************************************** - * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21] + * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21] Creates a status bar + * + * PARAMS + * style [I] + * text [I] + * parent [I] handle to the parent window + * wid [I] + * + * RETURNS + * Success: handle to the control + * Failure: 0 */ + HWND32 WINAPI CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid) { @@ -306,20 +331,51 @@ /*********************************************************************** - * CreateStatusWindow32W (COMCTL32.22) + * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control + * + * PARAMS + * style [I] + * text [I] + * parent [I] + * wid [I] + * + * RETURNS + * Success: handle to the control + * Failure: 0 */ -HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent, - UINT32 wid ) + +HWND32 WINAPI +CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid) { - return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style, + return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style, CW_USEDEFAULT32, CW_USEDEFAULT32, - CW_USEDEFAULT32, CW_USEDEFAULT32, + CW_USEDEFAULT32, CW_USEDEFAULT32, parent, wid, 0, 0); } + /*********************************************************************** - * CreateUpDownControl (COMCTL32.16) + * CreateUpDownControl [COMCTL32.16] Creates an Up-Down control + * + * PARAMS + * style + * x + * y + * cx + * cy + * parent + * id + * inst + * buddy + * maxVal [I] + * minVal [I] + * curVal [I] + * + * RETURNS + * Success: handle to the control + * Failure: 0 */ + HWND32 WINAPI CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy, HWND32 parent, INT32 id, HINSTANCE32 inst, @@ -344,7 +400,10 @@ * Registers the common controls. * * PARAMS - * None. + * No parameters. + * + * RETURNS + * No return values. * * NOTES * This function is just a dummy. @@ -364,7 +423,11 @@ * Registers the common controls. * * PARAMS - * lpInitCtrls [I] pointer to a INITCOMMONCONTROLS structure. + * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure. + * + * RETURNS + * Success: TRUE + * Failure: FALSE * * NOTES * Only the additinal common controls are registered by this function. @@ -399,37 +462,36 @@ case ICC_HOTKEY_CLASS: break; - /* advanced classes - not included in Win95 */ - case ICC_DATE_CLASSES: - TRACE (commctrl, "No month calendar class implemented!\n"); - TRACE (commctrl, "No date picker class implemented!\n"); - TRACE (commctrl, "No time picker class implemented!\n"); - UPDOWN_Register (); - break; + /* advanced classes - not included in Win95 */ + case ICC_DATE_CLASSES: + FIXME (commctrl, "No month calendar class implemented!\n"); + FIXME (commctrl, "No date picker class implemented!\n"); + FIXME (commctrl, "No time picker class implemented!\n"); + break; - case ICC_USEREX_CLASSES: - COMBOEX_Register (); - break; + case ICC_USEREX_CLASSES: + COMBOEX_Register (); + break; - case ICC_COOL_CLASSES: - REBAR_Register (); - break; + case ICC_COOL_CLASSES: + REBAR_Register (); + break; - case ICC_INTERNET_CLASSES: - TRACE (commctrl, "No IPAddress class implemented!\n"); - break; + case ICC_INTERNET_CLASSES: + FIXME (commctrl, "No IPAddress class implemented!\n"); + break; - case ICC_PAGESCROLLER_CLASS: - PAGER_Register (); - break; + case ICC_PAGESCROLLER_CLASS: + PAGER_Register (); + break; - case ICC_NATIVEFNTCTL_CLASS: - TRACE (commctrl, "No native font class implemented!\n"); - break; + case ICC_NATIVEFNTCTL_CLASS: + FIXME (commctrl, "No native font class implemented!\n"); + break; - default: - WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask); - break; + default: + WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask); + break; } } @@ -438,10 +500,26 @@ /*********************************************************************** - * CreateToolbarEx [COMCTL32.32] + * CreateToolbarEx [COMCTL32.32] Creates a tool bar window * + * PARAMS + * hwnd + * style + * wID + * nBitmaps + * hBMInst + * wBMID + * lpButtons + * iNumButtons + * dxButton + * dyButton + * dxBitmap + * dyBitmap + * uStructSize * - * + * RETURNS + * Success: handle to the tool bar control + * Failure: 0 */ HWND32 WINAPI @@ -600,10 +678,24 @@ /*********************************************************************** - * CreateToolbar [COMCTL32.7] + * CreateToolbar [COMCTL32.7] Creates a tool bar control * + * PARAMS + * hwnd + * style + * wID + * nBitmaps + * hBMInst + * wBMID + * lpButtons + * iNumButtons * + * RETURNS + * Success: handle to the tool bar control + * Failure: 0 * + * NOTES + * Do not use this functions anymore. Use CreateToolbarEx instead. */ HWND32 WINAPI @@ -625,22 +717,25 @@ * PARAMS * pdvi [O] pointer to version information structure. * - * REURNS + * RETURNS * Success: S_OK * Failure: E_INVALIDARG + * + * NOTES + * Returns version of a comctl32.dll from IE4.01 SP1. */ HRESULT WINAPI COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi) { if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) { - WARN(ver, "wrong DLLVERSIONINFO size from app"); + WARN (commctrl, "wrong DLLVERSIONINFO size from app"); return E_INVALIDARG; } pdvi->dwMajorVersion = 4; pdvi->dwMinorVersion = 72; - pdvi->dwBuildNumber = 2106; + pdvi->dwBuildNumber = 3110; pdvi->dwPlatformID = 1; TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c index 813512c..a2d86fc 100644 --- a/dlls/comctl32/header.c +++ b/dlls/comctl32/header.c
@@ -5,7 +5,7 @@ * * TODO: * - Imagelist support (partially). - * - Callback items. + * - Callback items (under construction). * - Order list support. * - Control specific cursors (over dividers). * - Hottrack support (partially). @@ -22,7 +22,6 @@ #include "windows.h" #include "commctrl.h" #include "header.h" -#include "heap.h" #include "win.h" #include "debug.h" @@ -446,7 +445,7 @@ HEADER_SendHeaderNotify (WND *wndPtr, UINT32 code, INT32 iItem) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); - NMHEADERA nmhdr; + NMHEADER32A nmhdr; HDITEM32A nmitem; nmhdr.hdr.hwndFrom = wndPtr->hwndSelf; @@ -455,11 +454,13 @@ nmhdr.iItem = iItem; nmhdr.iButton = 0; nmhdr.pitem = &nmitem; - nmitem.mask = infoPtr->items[iItem].mask; + nmitem.mask = 0; nmitem.cxy = infoPtr->items[iItem].cxy; nmitem.hbm = infoPtr->items[iItem].hbm; - nmitem.pszText = infoPtr->items[iItem].pszText; - nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; + nmitem.pszText = NULL; + nmitem.cchTextMax = 0; +// nmitem.pszText = infoPtr->items[iItem].pszText; +// nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; nmitem.fmt = infoPtr->items[iItem].fmt; nmitem.lParam = infoPtr->items[iItem].lParam; nmitem.iOrder = infoPtr->items[iItem].iOrder; @@ -473,7 +474,7 @@ static BOOL32 HEADER_SendClickNotify (WND *wndPtr, UINT32 code, INT32 iItem) { - NMHEADERA nmhdr; + NMHEADER32A nmhdr; nmhdr.hdr.hwndFrom = wndPtr->hwndSelf; nmhdr.hdr.idFrom = wndPtr->wIDmenu; @@ -499,21 +500,19 @@ HEADER_DeleteItem (WND *wndPtr, WPARAM32 wParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); + INT32 iItem = (INT32)wParam; HDC32 hdc; - INT32 iItem; - - iItem = (INT32)wParam; TRACE(header, "[iItem=%d]\n", iItem); - if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1)) + if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem)) return FALSE; if (infoPtr->uNumItem == 1) { TRACE(header, "Simple delete!\n"); if (infoPtr->items[0].pszText) - HeapFree (GetProcessHeap (), 0, infoPtr->items[0].pszText); - HeapFree (GetProcessHeap (), 0, infoPtr->items); + COMCTL32_Free (infoPtr->items[0].pszText); + COMCTL32_Free (infoPtr->items); infoPtr->items = 0; infoPtr->uNumItem = 0; } @@ -522,11 +521,10 @@ TRACE(header, "Complex delete! [iItem=%d]\n", iItem); if (infoPtr->items[iItem].pszText) - HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText); + COMCTL32_Free (infoPtr->items[iItem].pszText); infoPtr->uNumItem--; - infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); /* pre delete copy */ if (iItem > 0) { memcpy (&infoPtr->items[0], &oldItems[0], @@ -539,7 +537,7 @@ (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); } - HeapFree (GetProcessHeap (), 0, oldItems); + COMCTL32_Free (oldItems); } HEADER_SetItemBounds (wndPtr); @@ -565,60 +563,45 @@ HEADER_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); - HDITEM32A *phdi; - INT32 iItem; - UINT32 uMask; + HDITEM32A *phdi = (HDITEM32A*)lParam; + INT32 nItem = (INT32)wParam; + HEADER_ITEM *lpItem; - phdi = (HDITEM32A*)lParam; - iItem = (INT32)wParam; - - if (phdi == NULL) + if (!phdi) return FALSE; - if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1)) + if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem)) return FALSE; - TRACE (header, "[iItem=%d]\n", iItem); + TRACE (header, "[nItem=%d]\n", nItem); - uMask = phdi->mask; - if (uMask == 0) + if (phdi->mask == 0) return TRUE; - phdi->mask = 0; - if (uMask & infoPtr->items[iItem].mask & HDI_BITMAP) { - phdi->hbm = infoPtr->items[iItem].hbm; - phdi->mask |= HDI_BITMAP; + lpItem = (HEADER_ITEM*)&infoPtr->items[nItem]; + if (phdi->mask & HDI_BITMAP) + phdi->hbm = lpItem->hbm; + + if (phdi->mask & HDI_FORMAT) + phdi->fmt = lpItem->fmt; + + if (phdi->mask & HDI_WIDTH) + phdi->cxy = lpItem->cxy; + + if (phdi->mask & HDI_LPARAM) + phdi->lParam = lpItem->lParam; + + if (phdi->mask & HDI_TEXT) { + if (lpItem->pszText != LPSTR_TEXTCALLBACK32A) + lstrcpyn32A (phdi->pszText, lpItem->pszText, phdi->cchTextMax); + else + phdi->pszText = LPSTR_TEXTCALLBACK32A; } - if (uMask & infoPtr->items[iItem].mask & HDI_FORMAT) { - phdi->fmt = infoPtr->items[iItem].fmt; - phdi->mask |= HDI_FORMAT; - } + if (phdi->mask & HDI_IMAGE) + phdi->iImage = lpItem->iImage; - if (uMask & infoPtr->items[iItem].mask & HDI_WIDTH) { - phdi->cxy = infoPtr->items[iItem].cxy; - phdi->mask |= HDI_WIDTH; - } - - if (uMask & infoPtr->items[iItem].mask & HDI_LPARAM) { - phdi->lParam = infoPtr->items[iItem].lParam; - phdi->mask |= HDI_LPARAM; - } - - if (uMask & infoPtr->items[iItem].mask & HDI_TEXT) { - phdi->pszText = infoPtr->items[iItem].pszText; - phdi->cchTextMax = infoPtr->items[iItem].cchTextMax; - phdi->mask |= HDI_TEXT; - } - - if (uMask & infoPtr->items[iItem].mask & HDI_IMAGE) { - phdi->iImage = infoPtr->items[iItem].iImage; - phdi->mask |= HDI_IMAGE; - } - - if (uMask & infoPtr->items[iItem].mask & HDI_ORDER) { - phdi->iOrder = infoPtr->items[iItem].iOrder; - phdi->mask |= HDI_ORDER; - } + if (phdi->mask & HDI_ORDER) + phdi->iOrder = lpItem->iOrder; return TRUE; } @@ -637,13 +620,10 @@ HEADER_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); - INT32 iItem; - LPRECT32 lpRect; + INT32 iItem = (INT32)wParam; + LPRECT32 lpRect = (LPRECT32)lParam; - iItem = (INT32)wParam; - lpRect = (LPRECT32)lParam; - - if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1)) + if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem)) return FALSE; lpRect->left = infoPtr->items[iItem].rect.left; @@ -670,70 +650,72 @@ HEADER_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); - HDITEM32A *phdi = (HDITEM32A*)lParam; - INT32 iItem = (INT32)wParam; - HDC32 hdc; - INT32 len; + HDITEM32A *phdi = (HDITEM32A*)lParam; + INT32 nItem = (INT32)wParam; + HEADER_ITEM *lpItem; + HDC32 hdc; + INT32 len; - if (phdi == NULL) return -1; - if (iItem < 0) return -1; - if (iItem > infoPtr->uNumItem) - iItem = infoPtr->uNumItem; + if ((phdi == NULL) || (nItem < 0)) + return -1; + + if (nItem > infoPtr->uNumItem) + nItem = infoPtr->uNumItem; if (infoPtr->uNumItem == 0) { - infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (HEADER_ITEM)); + infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM)); infoPtr->uNumItem++; } else { HEADER_ITEM *oldItems = infoPtr->items; infoPtr->uNumItem++; - infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); /* pre insert copy */ - if (iItem > 0) { + if (nItem > 0) { memcpy (&infoPtr->items[0], &oldItems[0], - iItem * sizeof(HEADER_ITEM)); + nItem * sizeof(HEADER_ITEM)); } /* post insert copy */ - if (iItem < infoPtr->uNumItem - 1) { - memcpy (&infoPtr->items[iItem+1], &oldItems[iItem], - (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); + if (nItem < infoPtr->uNumItem - 1) { + memcpy (&infoPtr->items[nItem+1], &oldItems[nItem], + (infoPtr->uNumItem - nItem) * sizeof(HEADER_ITEM)); } - HeapFree (GetProcessHeap (), 0, oldItems); + COMCTL32_Free (oldItems); } - infoPtr->items[iItem].bDown = FALSE; + lpItem = (HEADER_ITEM*)&infoPtr->items[nItem]; + lpItem->bDown = FALSE; - infoPtr->items[iItem].mask = phdi->mask; if (phdi->mask & HDI_WIDTH) - infoPtr->items[iItem].cxy = phdi->cxy; + lpItem->cxy = phdi->cxy; if (phdi->mask & HDI_TEXT) { - len = lstrlen32A (phdi->pszText); - infoPtr->items[iItem].pszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); - lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText); - infoPtr->items[iItem].cchTextMax = phdi->cchTextMax; + if (phdi->pszText != LPSTR_TEXTCALLBACK32A) { + len = lstrlen32A (phdi->pszText); + lpItem->pszText = COMCTL32_Alloc (len+1); + lstrcpy32A (lpItem->pszText, phdi->pszText); + } + else + lpItem->pszText = LPSTR_TEXTCALLBACK32A; } if (phdi->mask & HDI_FORMAT) - infoPtr->items[iItem].fmt = phdi->fmt; + lpItem->fmt = phdi->fmt; if (phdi->mask & HDI_BITMAP) - infoPtr->items[iItem].hbm = phdi->hbm; + lpItem->hbm = phdi->hbm; if (phdi->mask & HDI_LPARAM) - infoPtr->items[iItem].lParam = phdi->lParam; + lpItem->lParam = phdi->lParam; if (phdi->mask & HDI_IMAGE) - infoPtr->items[iItem].iImage = phdi->iImage; + lpItem->iImage = phdi->iImage; if (phdi->mask & HDI_ORDER) - infoPtr->items[iItem].iOrder = phdi->iOrder; + lpItem->iOrder = phdi->iOrder; HEADER_SetItemBounds (wndPtr); @@ -741,7 +723,7 @@ HEADER_Refresh (wndPtr, hdc); ReleaseDC32 (wndPtr->hwndSelf, hdc); - return iItem; + return nItem; } @@ -798,60 +780,52 @@ { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); HDITEM32A *phdi = (HDITEM32A*)lParam; - INT32 iItem = (INT32)wParam; + INT32 nItem = (INT32)wParam; + HEADER_ITEM *lpItem; HDC32 hdc; if (phdi == NULL) return FALSE; - if ((iItem < 0) || (iItem > infoPtr->uNumItem - 1)) + if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem)) return FALSE; - TRACE (header, "[iItem=%d]\n", iItem); + TRACE (header, "[nItem=%d]\n", nItem); - if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, iItem)) + if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, nItem)) return FALSE; - if (phdi->mask & HDI_BITMAP) { - infoPtr->items[iItem].hbm = phdi->hbm; - infoPtr->items[iItem].mask |= HDI_BITMAP; - } + lpItem = (HEADER_ITEM*)&infoPtr->items[nItem]; + if (phdi->mask & HDI_BITMAP) + lpItem->hbm = phdi->hbm; - if (phdi->mask & HDI_FORMAT) { - infoPtr->items[iItem].fmt = phdi->fmt; - infoPtr->items[iItem].mask |= HDI_FORMAT; - } + if (phdi->mask & HDI_FORMAT) + lpItem->fmt = phdi->fmt; - if (phdi->mask & HDI_LPARAM) { - infoPtr->items[iItem].lParam = phdi->lParam; - infoPtr->items[iItem].mask |= HDI_LPARAM; - } + if (phdi->mask & HDI_LPARAM) + lpItem->lParam = phdi->lParam; if (phdi->mask & HDI_TEXT) { - INT32 len = lstrlen32A (phdi->pszText); - if (infoPtr->items[iItem].pszText) - HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText); - infoPtr->items[iItem].pszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); - lstrcpy32A (infoPtr->items[iItem].pszText, phdi->pszText); - infoPtr->items[iItem].cchTextMax = phdi->cchTextMax; + if (phdi->pszText != LPSTR_TEXTCALLBACK32A) { + INT32 len = lstrlen32A (phdi->pszText); + if (lpItem->pszText) + COMCTL32_Free (lpItem->pszText); + lpItem->pszText = COMCTL32_Alloc (len+1); + lstrcpy32A (lpItem->pszText, phdi->pszText); + } + else + lpItem->pszText = LPSTR_TEXTCALLBACK32A; } - if (phdi->mask & HDI_WIDTH) { - infoPtr->items[iItem].cxy = phdi->cxy; - infoPtr->items[iItem].mask |= HDI_WIDTH; - } + if (phdi->mask & HDI_WIDTH) + lpItem->cxy = phdi->cxy; - if (phdi->mask & HDI_IMAGE) { - infoPtr->items[iItem].iImage = phdi->iImage; - infoPtr->items[iItem].mask |= HDI_IMAGE; - } + if (phdi->mask & HDI_IMAGE) + lpItem->iImage = phdi->iImage; - if (phdi->mask & HDI_ORDER) { - infoPtr->items[iItem].iOrder = phdi->iOrder; - infoPtr->items[iItem].mask |= HDI_ORDER; - } + if (phdi->mask & HDI_ORDER) + lpItem->iOrder = phdi->iOrder; - HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, iItem); + HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, nItem); HEADER_SetItemBounds (wndPtr); hdc = GetDC32 (wndPtr->hwndSelf); @@ -870,8 +844,7 @@ HFONT32 hOldFont; HDC32 hdc; - infoPtr = (HEADER_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(HEADER_INFO)); + infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; infoPtr->uNumItem = 0; @@ -902,26 +875,28 @@ HEADER_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); - INT32 iItem; + HEADER_ITEM *lpItem; + INT32 nItem; if (infoPtr->items) { - for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) { - if (infoPtr->items[iItem].pszText) - HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText); + lpItem = (HEADER_ITEM*)infoPtr->items; + for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) { + if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) + COMCTL32_Free (lpItem->pszText); } - HeapFree (GetProcessHeap (), 0, infoPtr->items); + COMCTL32_Free (infoPtr->items); } if (infoPtr->himl) ImageList_Destroy (infoPtr->himl); - HeapFree (GetProcessHeap (), 0, infoPtr); + COMCTL32_Free (infoPtr); return 0; } -static LRESULT +static __inline__ LRESULT HEADER_GetFont (WND *wndPtr) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); @@ -935,16 +910,16 @@ { POINT32 pt; UINT32 flags; - INT32 iItem; + INT32 nItem; pt.x = (INT32)LOWORD(lParam); pt.y = (INT32)HIWORD(lParam); - HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem); + HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem); if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) - HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, iItem); + HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, nItem); else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) - HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, iItem); + HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, nItem); return 0; } @@ -956,45 +931,45 @@ HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); POINT32 pt; UINT32 flags; - INT32 iItem; + INT32 nItem; HDC32 hdc; pt.x = (INT32)LOWORD(lParam); pt.y = (INT32)HIWORD(lParam); - HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem); + HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem); if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) { SetCapture32 (wndPtr->hwndSelf); infoPtr->bCaptured = TRUE; infoPtr->bPressed = TRUE; - infoPtr->iMoveItem = iItem; + infoPtr->iMoveItem = nItem; - infoPtr->items[iItem].bDown = TRUE; + infoPtr->items[nItem].bDown = TRUE; /* Send WM_CUSTOMDRAW */ hdc = GetDC32 (wndPtr->hwndSelf); - HEADER_RefreshItem (wndPtr, hdc, iItem); + HEADER_RefreshItem (wndPtr, hdc, nItem); ReleaseDC32 (wndPtr->hwndSelf, hdc); - TRACE (header, "Pressed item %d!\n", iItem); + TRACE (header, "Pressed item %d!\n", nItem); } else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) { - if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, iItem))) { + if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, nItem))) { SetCapture32 (wndPtr->hwndSelf); infoPtr->bCaptured = TRUE; infoPtr->bTracking = TRUE; - infoPtr->iMoveItem = iItem; - infoPtr->nOldWidth = infoPtr->items[iItem].cxy; - infoPtr->xTrackOffset = infoPtr->items[iItem].rect.right - pt.x; + infoPtr->iMoveItem = nItem; + infoPtr->nOldWidth = infoPtr->items[nItem].cxy; + infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x; if (!(wndPtr->dwStyle & HDS_FULLDRAG)) { - infoPtr->xOldTrack = infoPtr->items[iItem].rect.right; + infoPtr->xOldTrack = infoPtr->items[nItem].rect.right; hdc = GetDC32 (wndPtr->hwndSelf); HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack); ReleaseDC32 (wndPtr->hwndSelf, hdc); } - TRACE (header, "Begin tracking item %d!\n", iItem); + TRACE (header, "Begin tracking item %d!\n", nItem); } } @@ -1008,15 +983,15 @@ HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); POINT32 pt; UINT32 flags; - INT32 iItem, nWidth; + INT32 nItem, nWidth; HDC32 hdc; pt.x = (INT32)LOWORD(lParam); pt.y = (INT32)HIWORD(lParam); - HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem); + HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem); if (infoPtr->bPressed) { - if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) { + if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) { infoPtr->items[infoPtr->iMoveItem].bDown = FALSE; hdc = GetDC32 (wndPtr->hwndSelf); HEADER_RefreshItem (wndPtr, hdc, infoPtr->iMoveItem); @@ -1040,8 +1015,7 @@ if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem)) infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth; else { - nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + - infoPtr->xTrackOffset; + nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; if (nWidth < 0) nWidth = 0; infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; @@ -1071,16 +1045,16 @@ HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); POINT32 pt; UINT32 flags; - INT32 iItem, nWidth; + INT32 nItem, nWidth; HDC32 hdc; pt.x = (INT32)LOWORD(lParam); pt.y = (INT32)HIWORD(lParam); - HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem); + HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem); if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) { if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN)) - infoPtr->iHotItem = iItem; + infoPtr->iHotItem = nItem; else infoPtr->iHotItem = -1; hdc = GetDC32 (wndPtr->hwndSelf); @@ -1090,7 +1064,7 @@ if (infoPtr->bCaptured) { if (infoPtr->bPressed) { - if ((iItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) + if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) infoPtr->items[infoPtr->iMoveItem].bDown = TRUE; else infoPtr->items[infoPtr->iMoveItem].bDown = FALSE; @@ -1105,8 +1079,7 @@ if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem)) infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth; else { - nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + - infoPtr->xTrackOffset; + nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; if (nWidth < 0) nWidth = 0; infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; @@ -1170,14 +1143,14 @@ HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr); POINT32 pt; UINT32 flags; - INT32 iItem; + INT32 nItem; TRACE (header, "code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam)); GetCursorPos32 (&pt); ScreenToClient32 (wndPtr->hwndSelf, &pt); - HEADER_InternalHitTest (wndPtr, &pt, &flags, &iItem); + HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem); if (flags == HHT_ONDIVIDER) SetCursor32 (infoPtr->hcurDivider); @@ -1238,18 +1211,25 @@ case HDM_GETITEM32A: return HEADER_GetItem32A (wndPtr, wParam, lParam); +// case HDM_GETITEM32W: + case HDM_GETITEMCOUNT: return HEADER_GetItemCount (wndPtr); case HDM_GETITEMRECT: return HEADER_GetItemRect (wndPtr, wParam, lParam); +// case HDM_GETORDERARRAY: +// case HDM_GETUNICODEFORMAT: + case HDM_HITTEST: return HEADER_HitTest (wndPtr, wParam, lParam); case HDM_INSERTITEM32A: return HEADER_InsertItem32A (wndPtr, wParam, lParam); +// case HDM_INSERTITEM32W: + case HDM_LAYOUT: return HEADER_Layout (wndPtr, wParam, lParam); @@ -1259,6 +1239,10 @@ case HDM_SETITEM32A: return HEADER_SetItem32A (wndPtr, wParam, lParam); +// case HDM_SETITEM32W: +// case HDM_SETORDERARRAY: +// case HDM_SETUNICODEFORMAT: + case WM_CREATE: return HEADER_Create (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index 6fbbd33..0aec07d 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c
@@ -5,9 +5,7 @@ * * TODO: * - Fix xBitmap and yBitmap in ImageList_DrawIndirect. - * - Fix ILD_TRANSPARENT error in ImageList_DrawIndirect. - * - Fix ImageList_GetIcon (might be a result of the - * ILD_TRANSPARENT error in ImageList_DrawIndirect). + * - Fix ImageList_GetIcon. * - Fix drag functions. * - Fix ImageList_Read and ImageList_Write. * - Fix ImageList_SetFilter (undocumented). @@ -146,11 +144,11 @@ { HDC32 hdcSrc, hdcDst; INT32 nFirstIndex, nImageCount; - INT32 nStartX, nRunX, nRunY; + INT32 nStartX; BITMAP32 bmp; - if (himl == NULL) return (-1); - if (hbmImage == 0) return (-1); + if (!himl || !hbmImage) + return -1; GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp); nImageCount = bmp.bmWidth / himl->cx; @@ -158,56 +156,33 @@ if (himl->cCurImage + nImageCount >= himl->cMaxImage) IMAGELIST_InternalExpandBitmaps (himl, nImageCount); + nStartX = himl->cCurImage * himl->cx; + hdcSrc = CreateCompatibleDC32 (0); hdcDst = CreateCompatibleDC32 (0); + /* copy image bitmap */ SelectObject32 (hdcDst, himl->hbmImage); SelectObject32 (hdcSrc, hbmImage); - BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0, bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY); if (himl->hbmMask) { if (hbmMask) { + /* copy mask bitmap */ SelectObject32 (hdcDst, himl->hbmMask); SelectObject32 (hdcSrc, hbmMask); - BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0, - bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY); - - /* fix transparent areas of the image bitmap*/ - SelectObject32 (hdcSrc, himl->hbmMask); - SelectObject32 (hdcDst, himl->hbmImage); - nStartX = himl->cCurImage * himl->cx; - - for (nRunY = 0; nRunY < himl->cy; nRunY++) { - for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) { - if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) != - RGB(0, 0, 0)) - SetPixel32 (hdcDst, nStartX + nRunX, nRunY, - RGB(0, 0, 0)); - } - } + BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy, + hdcSrc, 0, 0, SRCCOPY); } else { - /* create mask from the imagelist's background color */ + /* copy monochrome image to the mask bitmap */ SelectObject32 (hdcDst, himl->hbmMask); - SelectObject32 (hdcSrc, himl->hbmImage); - nStartX = himl->cCurImage * himl->cx; - for (nRunY = 0; nRunY < himl->cy; nRunY++) { - for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) { - if (GetPixel32 (hdcSrc, nStartX + nRunX, nRunY) == - himl->clrBk) - { - SetPixel32 (hdcSrc, nStartX + nRunX, nRunY, - RGB(0, 0, 0)); - SetPixel32 (hdcDst, nStartX + nRunX, nRunY, - RGB(255, 255, 255)); - } - else - SetPixel32 (hdcDst, nStartX + nRunX, nRunY, - RGB(0, 0, 0)); - } - } + SelectObject32 (hdcSrc, hbmImage); + SetBkColor32 (hdcSrc, GetNearestColor32 (hdcSrc, + GetPixel32 (hdcSrc, 0, 0))); + BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy, + hdcSrc, nStartX, 0, SRCCOPY); } } @@ -217,7 +192,7 @@ nFirstIndex = himl->cCurImage; himl->cCurImage += nImageCount; - return (nFirstIndex); + return nFirstIndex; } @@ -249,9 +224,9 @@ * specified bitmap using the mask color. * * PARAMS - * himl [I] image list handle. - * hbmImage [I] image bitmap handle. - * clrMask [I] mask color. + * himl [I] handle to image list. + * hBitmap [I] handle to bitmap + * clrMask [I] mask color. * * RETURNS * Success: Index of the first new image. @@ -259,20 +234,18 @@ */ INT32 WINAPI -ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hbmImage, COLORREF clrMask) +ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hBitmap, COLORREF clrMask) { - HDC32 hdcImageList, hdcImage, hdcMask; + HDC32 hdcImage, hdcMask, hdcBitmap; INT32 nIndex, nImageCount; BITMAP32 bmp; - INT32 nStartX, nRunX, nRunY; - COLORREF bkColor; if (himl == NULL) - return (-1); + return -1; - bkColor = (clrMask == CLR_NONE) ? himl->clrBk : clrMask; + if (!GetObject32A (hBitmap, sizeof(BITMAP32), &bmp)) + return -1; - GetObject32A (hbmImage, sizeof(BITMAP32), &bmp); nImageCount = bmp.bmWidth / himl->cx; if (himl->cCurImage + nImageCount >= himl->cMaxImage) @@ -281,39 +254,34 @@ nIndex = himl->cCurImage; himl->cCurImage += nImageCount; - hdcImageList = CreateCompatibleDC32 (0); - hdcImage = CreateCompatibleDC32 (0); + hdcImage = CreateCompatibleDC32 (0); + hdcBitmap = CreateCompatibleDC32 (0); - SelectObject32 (hdcImageList, himl->hbmImage); - SelectObject32 (hdcImage, hbmImage); - BitBlt32 (hdcImageList, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy, - hdcImage, 0, 0, SRCCOPY); + SelectObject32 (hdcBitmap, hBitmap); + SelectObject32 (hdcImage, himl->hbmImage); + BitBlt32 (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy, + hdcBitmap, 0, 0, SRCCOPY); if (himl->hbmMask) { - /* create Mask */ + COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask : + GetNearestColor32 (hdcBitmap, GetPixel32 (hdcBitmap, 0, 0)); + + /* create mask from image */ hdcMask = CreateCompatibleDC32 (0); SelectObject32 (hdcMask, himl->hbmMask); - nStartX = nIndex * himl->cx; - for (nRunY = 0; nRunY < himl->cy; nRunY++) { - for (nRunX = 0; nRunX < bmp.bmWidth; nRunX++) { - if (GetPixel32 (hdcImageList, nStartX + nRunX, nRunY) == - bkColor) { - SetPixel32 (hdcImageList, nStartX + nRunX, nRunY, - RGB(0, 0, 0)); - SetPixel32 (hdcMask, nStartX + nRunX, nRunY, - RGB(255, 255, 255)); - } - else - SetPixel32 (hdcMask, nStartX + nRunX, nRunY, RGB(0, 0, 0)); - } - } + + /* create monochrome image to the mask bitmap */ + SetBkColor32 (hdcBitmap, bkColor); + BitBlt32 (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy, + hdcBitmap, 0, 0, SRCCOPY); + DeleteDC32 (hdcMask); } - DeleteDC32 (hdcImageList); DeleteDC32 (hdcImage); + DeleteDC32 (hdcBitmap); - return (nIndex); + return nIndex; } @@ -969,6 +937,8 @@ { /* draw the mask */ SelectObject32 (hdcImageList, himlLocal->hbmMask); + SetBkColor32 (hdcImageList, RGB(255, 255, 255)); + SetTextColor32 (hdcImageList, RGB(0, 0, 0)); BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hdcImageList, himlLocal->cx * pimldp->i, 0, bMaskTrans ? SRCAND : SRCCOPY); @@ -989,8 +959,7 @@ } BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, - hdcImageList, himlLocal->cx * pimldp->i, 0, - SRCPAINT); + hdcImageList, himlLocal->cx * pimldp->i, 0, SRCPAINT); if (bBlend25 || bBlend50) { @@ -1225,7 +1194,7 @@ { ICONINFO ii; HICON32 hIcon; - HDC32 hdc; + HDC32 hdcSrc, hdcDst; INT32 nWidth, nHeight; if (himl == NULL) return 0; @@ -1234,27 +1203,36 @@ nWidth = GetSystemMetrics32 (SM_CXICON); nHeight = GetSystemMetrics32 (SM_CYICON); + hdcSrc = CreateCompatibleDC32(0); + hdcDst = CreateCompatibleDC32(0); + ii.fIcon = TRUE; ii.xHotspot = 0; ii.yHotspot = 0; - ii.hbmMask = CreateBitmap32 (nWidth, nHeight, 1, 1, NULL); - ii.hbmColor = CreateBitmap32 (nWidth, nHeight, 1, himl->uBitsPixel, NULL); + ii.hbmMask = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight); + ii.hbmColor = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight); - hdc = CreateCompatibleDC32(0); - - /* draw image*/ - SelectObject32 (hdc, ii.hbmColor); - PatBlt32 (hdc, 0, 0, nWidth, nHeight, BLACKNESS); - ImageList_Draw (himl, i, hdc, 0, 0, fStyle | ILD_TRANSPARENT); /* draw mask*/ - SelectObject32 (hdc, ii.hbmMask); - PatBlt32 (hdc, 0, 0, nWidth, nHeight, WHITENESS); - ImageList_Draw (himl, i, hdc, 0, 0, fStyle | ILD_MASK); + SelectObject32 (hdcDst, ii.hbmMask); + if (himl->hbmMask) { + SelectObject32 (hdcSrc, himl->hbmMask); + BitBlt32 (hdcDst, 0, 0, nWidth, nHeight, + hdcSrc, i * himl->cx, 0, SRCCOPY); + } + else + PatBlt32 (hdcDst, 0, 0, nWidth, nHeight, BLACKNESS); + + /* draw image*/ + SelectObject32 (hdcDst, ii.hbmColor); + SelectObject32 (hdcSrc, himl->hbmImage); + BitBlt32 (hdcDst, 0, 0, nWidth, nHeight, + hdcSrc, i * himl->cx, 0, SRCCOPY); hIcon = CreateIconIndirect (&ii); - DeleteDC32 (hdc); + DeleteDC32 (hdcSrc); + DeleteDC32 (hdcDst); DeleteObject32 (ii.hbmMask); DeleteObject32 (ii.hbmColor); @@ -2040,7 +2018,7 @@ * Sets the image size of the bitmap and deletes all images. * * PARAMS - * himl [I] image list handle + * himl [I] handle to image list * cx [I] image width * cy [I] image height * @@ -2054,7 +2032,8 @@ { INT32 nCount; - if (himl == NULL) return (FALSE); + if (!himl) + return FALSE; /* remove all images*/ himl->cMaxImage = himl->cInitial + himl->cGrow; @@ -2088,7 +2067,7 @@ * Resizes an image list to the specified number of images. * * PARAMS - * himl [I] image list handle + * himl [I] handle to image list * iImageCount [I] number of images in the image list * * RETURNS @@ -2103,9 +2082,12 @@ HBITMAP32 hbmNewBitmap; INT32 nNewCount, nCopyCount; - if (himl == NULL) return (FALSE); - if (himl->cCurImage <= iImageCount) return (FALSE); - if (himl->cMaxImage > iImageCount) return (TRUE); + if (!himl) + return FALSE; + if (himl->cCurImage <= iImageCount) + return FALSE; + if (himl->cMaxImage > iImageCount) + return TRUE; nNewCount = iImageCount + himl->cGrow; nCopyCount = _MIN(himl->cCurImage, iImageCount); @@ -2126,7 +2108,7 @@ } else { - WARN (imagelist, "Could not create new image bitmap !\n"); + ERR (imagelist, "Could not create new image bitmap !\n"); } if (himl->hbmMask) @@ -2144,7 +2126,7 @@ } else { - WARN (imagelist, "Could not create new mask bitmap!\n"); + ERR (imagelist, "Could not create new mask bitmap!\n"); } } @@ -2156,7 +2138,7 @@ if (himl->cCurImage > nCopyCount) himl->cCurImage = nCopyCount; - return (TRUE); + return TRUE; } @@ -2178,8 +2160,12 @@ BOOL32 WINAPI ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay) { - if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE)) return (FALSE); - if ((iImage < 0) || (iImage > himl->cCurImage)) return (FALSE); + if (!himl) + return FALSE; + if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE)) + return FALSE; + if ((iImage < 0) || (iImage > himl->cCurImage)) + return FALSE; himl->nOvlIdx[iOverlay - 1] = iImage; return TRUE; @@ -2210,9 +2196,10 @@ BOOL32 WINAPI ImageList_Write (HIMAGELIST himl, LPSTREAM32 pstm) { - FIXME (imagelist, "empty stub!\n"); + if (!himl) + return FALSE; - if (himl == NULL) return (FALSE); + FIXME (imagelist, "empty stub!\n"); return FALSE; }
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 91fe4cb..0c24d9c 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c
@@ -9,8 +9,8 @@ * Eric <ekohl@abo.rhein-zeitung.de> * * TODO: - * - All messages. - * - All notifications. + * - Most messages. + * - Most notifications. */ #include "windows.h" @@ -26,7 +26,7 @@ static VOID LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); +// LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); @@ -34,6 +34,124 @@ +// << LISTVIEW_ApproximateViewRect >> +// << LISTVIEW_Arrange >> +// << LISTVIEW_CreateDragImage >> + + +static LRESULT +LISTVIEW_DeleteAllItems (WND *wndPtr) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + INT32 nItem; + LISTVIEW_ITEM *lpItem; + NMLISTVIEW nmlv; + BOOL32 bNotify; + + if (infoPtr->nItemCount == 0) + return TRUE; + + TRACE (listview, "\n"); + + /* send LVN_DELETEALLITEMS notification */ + ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = LVN_DELETEALLITEMS; + nmlv.iItem = -1; + bNotify = + !(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + nmlv.hdr.code = LVN_DELETEITEM; + + for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) { + /* send notification */ + if (bNotify) { + nmlv.iItem = nItem; + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + } + + /* get item pointer */ + lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem); + + /* delete item strings */ + if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) + COMCTL32_Free (lpItem->pszText); + + /* free item data */ + COMCTL32_Free (lpItem); + } + + DPA_DeleteAllPtrs (infoPtr->hdpaItems); + infoPtr->nItemCount = 0; + + return TRUE; +} + + +static LRESULT +LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + INT32 nColumn = (INT32)wParam; + + /* FIXME ??? */ + if (infoPtr->nItemCount > 0) + return FALSE; + + if (!SendMessage32A (infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0)) + return FALSE; + + infoPtr->nColumnCount--; + + FIXME (listview, "semi stub!\n"); + + return TRUE; +} + + +static LRESULT +LISTVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + INT32 nItem = (INT32)wParam; + LISTVIEW_ITEM *lpItem; + NMLISTVIEW nmlv; + + if ((nItem < 0) || (nItem >= infoPtr->nItemCount)) + return FALSE; + + TRACE (listview, "(%d)\n", nItem); + + /* send notification */ + ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = LVN_DELETEITEM; + nmlv.iItem = nItem; + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + /* remove from item array */ + lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem); + + /* delete item strings */ + if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) + COMCTL32_Free (lpItem->pszText); + + /* free item data */ + COMCTL32_Free (lpItem); + + infoPtr->nItemCount--; + + return TRUE; +} + + +// << LISTVIEW_EditLabel >> +// << LISTVIEW_EnsureVisible >> // << LISTVIEW_FindItem >> @@ -47,6 +165,75 @@ // << LISTVIEW_GetBkImage >> +// << LISTVIEW_GetCallbackMask >> + + +static LRESULT +LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; + INT32 nIndex = (INT32)wParam; + HDITEM32A hdi; + + if (!lpcol) + return FALSE; + + TRACE (listview, "(%d %p)\n", nIndex, lpcol); + + ZeroMemory (&hdi, sizeof(HDITEM32A)); + + if (lpcol->mask & LVCF_FMT) + hdi.mask |= HDI_FORMAT; + + if (lpcol->mask & LVCF_WIDTH) + hdi.mask |= HDI_WIDTH; + + if (lpcol->mask & LVCF_TEXT) + hdi.mask |= (HDI_TEXT | HDI_FORMAT); + + if (lpcol->mask & LVCF_IMAGE) + hdi.mask |= HDI_IMAGE; + + if (lpcol->mask & LVCF_ORDER) + hdi.mask |= HDI_ORDER; + + if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A, + wParam, (LPARAM)&hdi)) + return FALSE; + + if (lpcol->mask & LVCF_FMT) { + lpcol->fmt = 0; + + if (hdi.fmt & HDF_LEFT) + lpcol->fmt |= LVCFMT_LEFT; + else if (hdi.fmt & HDF_RIGHT) + lpcol->fmt |= LVCFMT_RIGHT; + else if (hdi.fmt & HDF_CENTER) + lpcol->fmt |= LVCFMT_CENTER; + + if (hdi.fmt & HDF_IMAGE) + lpcol->fmt |= LVCFMT_COL_HAS_IMAGES; + } + + if (lpcol->mask & LVCF_WIDTH) + lpcol->cx = hdi.cxy; + + if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText)) + lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax); + + if (lpcol->mask & LVCF_IMAGE) + lpcol->iImage = hdi.iImage; + + if (lpcol->mask & LVCF_ORDER) + lpcol->iOrder = hdi.iOrder; + + return TRUE; +} + + +// << LISTVIEW_GetColumn32W >> +// << LISTVIEW_GetColumnOrderArray >> __inline__ static LRESULT @@ -64,6 +251,9 @@ } +// << LISTVIEW_GetCountPerPage >> +// << LISTVIEW_GetEditControl >> +// << LISTVIEW_GetExtendedListviewStyle >> __inline__ static LRESULT @@ -75,6 +265,11 @@ } +// << LISTVIEW_GetHotCursor >> +// << LISTVIEW_GetHotItem >> +// << LISTVIEW_GetHoverTime >> + + static LRESULT LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { @@ -97,19 +292,62 @@ } +// << LISTVIEW_GetISearchString >> + + static LRESULT LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVITEM32A lpItem = (LPLVITEM32A)lParam; + LISTVIEW_ITEM *lpRow, *lpSubItem; - FIXME (listview, "(0x%08x) empty stub!\n", wParam); + if (!lpItem) + return FALSE; + if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount)) + return FALSE; + if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount)) + return FALSE; + + FIXME (listview, "(%d %d %p)\n", + lpItem->iItem, lpItem->iSubItem, lpItem); + + lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); + if (!lpRow) + return FALSE; + + lpSubItem = &lpRow[lpItem->iSubItem]; + if (!lpSubItem) + return FALSE; + + if (lpItem->mask & LVIF_STATE) + lpItem->state = lpSubItem->state & lpItem->stateMask; + + if (lpItem->mask & LVIF_TEXT) { + if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) + lpItem->pszText = LPSTR_TEXTCALLBACK32A; + else + Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText, + lpItem->cchTextMax); + } + + if (lpItem->mask & LVIF_IMAGE) + lpItem->iImage = lpSubItem->iImage; + + if (lpItem->mask & LVIF_PARAM) + lpItem->lParam = lpSubItem->lParam; + + if (lpItem->mask & LVIF_INDENT) + lpItem->iIndent = lpSubItem->iIndent; return TRUE; } +// << LISTVIEW_GetItem32W >> + __inline__ static LRESULT LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) @@ -119,6 +357,93 @@ } +static LRESULT +LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPPOINT32 lpPt = (LPPOINT32)lParam; + INT32 nIndex = (INT32)wParam; + + if (!lpPt) + return FALSE; + if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount)) + return FALSE; + + FIXME (listview, "returning position [0,0]!\n"); + lpPt->x = 0; + lpPt->y = 0; + + return TRUE; +} + + +// << LISTVIEW_GetItemRect >> +// << LISTVIEW_GetItemSpacing >> +// << LISTVIEW_GetItemState >> + + +static LRESULT +LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVITEM32A lpItem = (LPLVITEM32A)lParam; + INT32 nItem = (INT32)wParam; + LISTVIEW_ITEM *lpRow, *lpSubItem; + + TRACE (listview, "(%d %p)\n", nItem, lpItem); + + lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); + if (!lpRow) + return 0; + + lpSubItem = &lpRow[lpItem->iSubItem]; + if (!lpSubItem) + return 0; + + if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) { + lpItem->pszText = LPSTR_TEXTCALLBACK32A; + return 0; + } + else + return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText, + lpItem->cchTextMax); +} + + +// << LISTVIEW_GetItemText32A >> + + +static LRESULT +LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + INT32 nStart = (INT32)wParam; + UINT32 uFlags = (UINT32)LOWORD(lParam); + + FIXME (listview, "(%d, 0x%x); empty stub!\n", nStart, uFlags); + + + return -1; +} + + +// << LISTVIEW_GetNumberOfWorkAreas >> +// << LISTVIEW_GetOrigin >> + + +static LRESULT +LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + TRACE (listview, ": empty stub (returns 0)!\n"); + + return 0; +} + + +// << LISTVIEW_GetSelectionMark >> + static LRESULT LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) @@ -132,7 +457,7 @@ if (!lpsz) return 0; - TRACE (listview, "(%s) empty stub!\n", lpsz); + TRACE (listview, "(%s)\n", lpsz); hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT); hdc = GetDC32 (0); @@ -149,22 +474,42 @@ +__inline__ static LRESULT +LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + return infoPtr->clrTextBk; +} + + +__inline__ static LRESULT +LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + return infoPtr->clrText; +} + + static LRESULT LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; + INT32 nIndex = (INT32)wParam; HDITEM32A hdi; + INT32 nResult; - if (!lpcol) + if ((!lpcol) || (infoPtr->nItemCount > 0)) return -1; - TRACE (listview, "(%d %p) empty stub!\n", (INT32)wParam, lpcol); + FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol); ZeroMemory (&hdi, sizeof(HDITEM32A)); if (lpcol->mask & LVCF_FMT) { - if (wParam == 0) + if (nIndex == 0) hdi.fmt |= HDF_LEFT; else if (lpcol->fmt & LVCFMT_LEFT) hdi.fmt |= HDF_LEFT; @@ -200,11 +545,90 @@ hdi.iOrder = lpcol->iOrder; } - return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A, - wParam, (LPARAM)&hdi); + nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A, + wParam, (LPARAM)&hdi); + if (nResult == -1) + return -1; + + infoPtr->nColumnCount++; + + return nResult; } +// << LISTVIEW_InsertColumn32W >> + + +static LRESULT +LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVITEM32A lpItem = (LPLVITEM32A)lParam; + LISTVIEW_ITEM *lpListItem; + INT32 nIndex; + NMLISTVIEW nmlv; + + if (!lpItem) + return -1; + + if ((!infoPtr->nColumnCount) || (lpItem->iSubItem)) + return -1; + + FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem); + + lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM)); + nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem); + if (nIndex == -1) + return -1; + + if (lpItem->mask & LVIF_STATE) + lpListItem[0].state = lpItem->state; + + if (lpItem->mask & LVIF_TEXT) { + if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) + lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A; + else + Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText); + } + + if (lpItem->mask & LVIF_IMAGE) + lpListItem[0].iImage = lpItem->iImage; + + if (lpItem->mask & LVIF_PARAM) + lpListItem[0].lParam = lpItem->lParam; + + if (lpItem->mask & LVIF_INDENT) + lpListItem[0].iIndent = lpItem->iIndent; + + infoPtr->nItemCount++; + + /* send notification */ + ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = LVN_INSERTITEM; + nmlv.iItem = nIndex; + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + return nIndex; +} + + +// << LISTVIEW_InsertItem32W >> + + +static LRESULT +LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ +// LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + FIXME (listview, "(%d - %d): empty stub!\n", + (INT32)wParam, (INT32)lParam); + + return TRUE; +} + static LRESULT @@ -212,10 +636,11 @@ { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - if (!(infoPtr)) return FALSE; + if (!infoPtr) + return FALSE; /* set background color */ - TRACE (listview, "0x%06x\n", (COLORREF)lParam); + TRACE (listview, "0x%06lx\n", (COLORREF)lParam); infoPtr->clrBk = (COLORREF)lParam; return TRUE; @@ -223,6 +648,65 @@ static LRESULT +LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; + INT32 nIndex = (INT32)wParam; + HDITEM32A hdi; + + if (!lpcol) + return -1; + + FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol); + + ZeroMemory (&hdi, sizeof(HDITEM32A)); + + if (lpcol->mask & LVCF_FMT) { + if (nIndex == 0) + hdi.fmt |= HDF_LEFT; + else if (lpcol->fmt & LVCFMT_LEFT) + hdi.fmt |= HDF_LEFT; + else if (lpcol->fmt & LVCFMT_RIGHT) + hdi.fmt |= HDF_RIGHT; + else if (lpcol->fmt & LVCFMT_CENTER) + hdi.fmt |= HDF_CENTER; + + if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES) + hdi.fmt |= HDF_IMAGE; + + hdi.mask |= HDI_FORMAT; + } + + if (lpcol->mask & LVCF_WIDTH) { + hdi.mask |= HDI_WIDTH; + hdi.cxy = lpcol->cx; + } + + if (lpcol->mask & LVCF_TEXT) { + hdi.mask |= (HDI_TEXT | HDI_FORMAT); + hdi.pszText = lpcol->pszText; + hdi.fmt |= HDF_STRING; + } + + if (lpcol->mask & LVCF_IMAGE) { + hdi.mask |= HDI_IMAGE; + hdi.iImage = lpcol->iImage; + } + + if (lpcol->mask & LVCF_ORDER) { + hdi.mask |= HDI_ORDER; + hdi.iOrder = lpcol->iOrder; + } + + return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A, + wParam, (LPARAM)&hdi); +} + + + + +static LRESULT LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); @@ -252,6 +736,150 @@ +static LRESULT +LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPLVITEM32A lpItem = (LPLVITEM32A)lParam; + LISTVIEW_ITEM *lpRow, *lpSubItem; + NMLISTVIEW nmlv; + + if (!lpItem) + return FALSE; + + if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount)) + return FALSE; + + if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount)) + return FALSE; + + /* send LVN_ITEMCHANGING notification */ + ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = LVN_ITEMCHANGING; + nmlv.iItem = lpItem->iItem; + nmlv.iSubItem = lpItem->iSubItem; + nmlv.uChanged = lpItem->mask; + + if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv)) + return FALSE; + + TRACE (listview, "(%d %d %p)\n", + lpItem->iItem, lpItem->iSubItem, lpItem); + + lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); + if (!lpRow) + return FALSE; + + lpSubItem = &lpRow[lpItem->iSubItem]; + if (!lpSubItem) + return FALSE; + + if (lpItem->mask & LVIF_STATE) + lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state; + + if (lpItem->mask & LVIF_TEXT) { + if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) { + if ((lpSubItem->pszText) && + (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A)) + COMCTL32_Free (lpSubItem->pszText); + lpSubItem->pszText = LPSTR_TEXTCALLBACK32A; + } + else { + if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) + lpSubItem->pszText = NULL; + Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText); + } + } + + if (lpItem->mask & LVIF_IMAGE) + lpSubItem->iImage = lpItem->iImage; + + if (lpItem->mask & LVIF_PARAM) + lpSubItem->lParam = lpItem->lParam; + + if (lpItem->mask & LVIF_INDENT) + lpSubItem->iIndent = lpItem->iIndent; + + /* send LVN_ITEMCHANGED notification */ + nmlv.hdr.code = LVN_ITEMCHANGED; + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + return TRUE; +} + + +// << LISTVIEW_SetItem32W >> +// << LISTVIEW_SetItemCount >> + + +static LRESULT +LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + INT32 nIndex = (INT32)wParam; + + if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount)) + return FALSE; + + FIXME (listview, "setting position [%d, %d]!\n", + (INT32)LOWORD(lParam), (INT32)HIWORD(lParam)); + + /* FIXME: set position */ + + return TRUE; +} + + +static LRESULT +LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + if (!infoPtr) + return FALSE; + + /* set text background color */ + TRACE (listview, "0x%06lx\n", (COLORREF)lParam); + infoPtr->clrTextBk = (COLORREF)lParam; + + return TRUE; +} + + +static LRESULT +LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + if (!infoPtr) + return FALSE; + + /* set text color */ + TRACE (listview, "0x%06lx\n", (COLORREF)lParam); + infoPtr->clrText = (COLORREF)lParam; + + return TRUE; +} + + + +static LRESULT +LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ +// LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + + FIXME (listview, "empty stub!\n"); + + /* fake success */ + return TRUE; +} + + + static LRESULT LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) @@ -261,9 +889,13 @@ LOGFONT32A logFont; DWORD dwStyle = WS_CHILD | WS_VISIBLE; + TRACE (listview, "styles 0x%08lx 0x%08lx\n", + wndPtr->dwStyle, wndPtr->dwExStyle); /* initialize info structure */ infoPtr->clrBk = CLR_NONE; + infoPtr->clrText = RGB(0, 0, 0); /* preliminary */ + infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */ if (!(wndPtr->dwStyle & LVS_REPORT) || (wndPtr->dwStyle & LVS_NOCOLUMNHEADER)) @@ -286,8 +918,7 @@ SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, (WPARAM32)infoPtr->hFont, (LPARAM)TRUE); - - infoPtr->hdsaItems = DSA_Create (sizeof(LISTVIEW_ITEM), 10); + infoPtr->hdpaItems = DPA_Create (10); return 0; } @@ -298,7 +929,11 @@ { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - DSA_Destroy (infoPtr->hdsaItems); + /* delete all items */ + LISTVIEW_DeleteAllItems (wndPtr); + + /* destroy dpa */ + DPA_Destroy (infoPtr->hdpaItems); /* destroy header */ if (infoPtr->hwndHeader) @@ -330,7 +965,8 @@ DeleteObject32 (hBrush); return FALSE; } - return FALSE; + + return TRUE; } @@ -345,7 +981,78 @@ // << LISTVIEW_HScroll >> // << LISTVIEW_KeyDown >> -// << LISTVIEW_KillFocus >> + + +static LRESULT +LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMHDR nmh; + + FIXME (listview, "semi stub!\n"); + + nmh.hwndFrom = wndPtr->hwndSelf; + nmh.idFrom = wndPtr->wIDmenu; + nmh.code = NM_KILLFOCUS; + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh); + + infoPtr->bFocus = FALSE; + + return 0; +} + + +static LRESULT +LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMLISTVIEW nmlv; + + FIXME (listview, "semi stub!\n"); + + ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = NM_DBLCLK; + nmlv.iItem = -1; + nmlv.iSubItem = 0; + nmlv.ptAction.x = (INT32)LOWORD(lParam); + nmlv.ptAction.y = (INT32)HIWORD(lParam); + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + return 0; +} + + +static LRESULT +LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMLISTVIEW nmlv; + + FIXME (listview, "semi stub!\n"); + + ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = NM_CLICK; + nmlv.iItem = -1; + nmlv.iSubItem = 0; + nmlv.ptAction.x = (INT32)LOWORD(lParam); + nmlv.ptAction.y = (INT32)HIWORD(lParam); + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + if (!infoPtr->bFocus) + SetFocus32 (wndPtr->hwndSelf); + + return 0; +} static LRESULT @@ -387,6 +1094,25 @@ static LRESULT +LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LPNMHDR lpnmh = (LPNMHDR)lParam; + + if (lpnmh->hwndFrom == infoPtr->hwndHeader) { + + FIXME (listview, "WM_NOTIFY from header!\n"); + } + else { + + FIXME (listview, "WM_NOTIFY from unknown source!\n"); + } + + return 0; +} + + +static LRESULT LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam) { HDC32 hdc; @@ -400,6 +1126,73 @@ } +static LRESULT +LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMLISTVIEW nmlv; + + FIXME (listview, "semi stub!\n"); + + ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = NM_RDBLCLK; + nmlv.iItem = -1; + nmlv.iSubItem = 0; + nmlv.ptAction.x = (INT32)LOWORD(lParam); + nmlv.ptAction.y = (INT32)HIWORD(lParam); + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + return 0; +} + + +static LRESULT +LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMLISTVIEW nmlv; + + FIXME (listview, "semi stub!\n"); + + ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); + nmlv.hdr.hwndFrom = wndPtr->hwndSelf; + nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.code = NM_RCLICK; + nmlv.iItem = -1; + nmlv.iSubItem = 0; + nmlv.ptAction.x = (INT32)LOWORD(lParam); + nmlv.ptAction.y = (INT32)HIWORD(lParam); + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + + return 0; +} + + +static LRESULT +LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + NMHDR nmh; + + FIXME (listview, "semi stub!\n"); + + nmh.hwndFrom = wndPtr->hwndSelf; + nmh.idFrom = wndPtr->wIDmenu; + nmh.code = NM_SETFOCUS; + + SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh); + + infoPtr->bFocus = TRUE; + + return 0; +} static LRESULT @@ -433,24 +1226,28 @@ LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - HDLAYOUT hl; - WINDOWPOS32 wp; - RECT32 rc; - - rc.top = 0; - rc.left = 0; - rc.right = LOWORD(lParam); - rc.bottom = HIWORD(lParam); - - hl.prc = &rc; - hl.pwpos = ℘ - SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl); - - SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf, - wp.x, wp.y, wp.cx, wp.cy, wp.flags); GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList); - infoPtr->rcList.top += wp.cy; + + if (wndPtr->dwStyle & LVS_REPORT) { + HDLAYOUT hl; + WINDOWPOS32 wp; + RECT32 rc; + + rc.top = 0; + rc.left = 0; + rc.right = LOWORD(lParam); + rc.bottom = HIWORD(lParam); + + hl.prc = &rc; + hl.pwpos = ℘ + SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl); + + SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf, + wp.x, wp.y, wp.cx, wp.cy, wp.flags); + + infoPtr->rcList.top += wp.cy; + } return 0; } @@ -463,24 +1260,54 @@ switch (uMsg) { -// case LVM_DELETEALLITEMS: +// case LVM_APPROXIMATEVIEWRECT: +// case LVM_ARRANGE: +// case LVM_CREATEDRAGIMAGE: - case LVM_GETBKCOLOR: + case LVM_DELETEALLITEMS: + return LISTVIEW_DeleteAllItems (wndPtr); + + case LVM_DELETECOLUMN: + return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam); + + case LVM_DELETEITEM: + return LISTVIEW_DeleteItem (wndPtr, wParam, lParam); + +// case LVM_EDITLABEL: +// case LVM_ENSUREVISIBLE: +// case LVM_FINDITEM: + + case LVM_GETBKCOLOR: return LISTVIEW_GetBkColor (wndPtr, wParam, lParam); +// case LVM_GETBKIMAGE: +// case LVM_GETCALLBACKMASK: - case LVM_GETCOLUMNWIDTH: + case LVM_GETCOLUMN32A: + return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam); + +// case LVM_GETCOLUMN32W: +// case LVM_GETCOLUMNORDERARRAY: + + case LVM_GETCOLUMNWIDTH: return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam); +// case LVM_GETCOUNTPERPAGE: +// case LVM_GETEDITCONTROL: +// case LVM_GETEXTENDEDLISTVIEWSTYLE: - case LVM_GETHEADER: + case LVM_GETHEADER: return LISTVIEW_GetHeader (wndPtr, wParam, lParam); -// case LVM_GETISEARCHSTRING: +// case LVM_GETHOTCURSOR: +// case LVM_GETHOTITEM: +// case LVM_GETHOVERTIME: case LVM_GETIMAGELIST: return LISTVIEW_GetImageList (wndPtr, wParam, lParam); +// case LVM_GETISEARCHSTRING: + case LVM_GETITEM32A: return LISTVIEW_GetItem32A (wndPtr, wParam, lParam); @@ -489,7 +1316,28 @@ case LVM_GETITEMCOUNT: return LISTVIEW_GetItemCount (wndPtr, wParam, lParam); -// case LVM_GETSELECTEDCOUNT: + case LVM_GETITEMPOSITION: + return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam); + +// case LVM_GETITEMRECT: +// case LVM_GETITEMSPACING: +// case LVM_GETITEMSTATE: + + case LVM_GETITEMTEXT32A: + return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam); + +// case LVM_GETITEMTEXT32W: + + case LVM_GETNEXTITEM: + return LISTVIEW_GetNextItem (wndPtr, wParam, lParam); + +// case LVM_GETNUMBEROFWORKAREAS: +// case LVM_GETORIGIN: + + case LVM_GETSELECTEDCOUNT: + return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam); + +// case LVM_GETSELECTIONMARK: case LVM_GETSTRINGWIDTH32A: return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam); @@ -497,26 +1345,85 @@ // case LVM_GETSTRINGWIDTH32W: // case LVM_GETSUBITEMRECT: + case LVM_GETTEXTBKCOLOR: + return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam); + + case LVM_GETTEXTCOLOR: + return LISTVIEW_GetTextColor (wndPtr, wParam, lParam); + +// case LVM_GETTOOLTIPS: +// case LVM_GETTOPINDEX: +// case LVM_GETUNICODEFORMAT: +// case LVM_GETVIEWRECT: +// case LVM_GETWORKAREAS: +// case LVM_HITTEST: + case LVM_INSERTCOLUMN32A: return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam); - // case LVM_INSERTCOLUMN32W: -// case LVM_INSERTITEM32A: + case LVM_INSERTITEM32A: + return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam); + // case LVM_INSERTITEM32W: + case LVM_REDRAWITEMS: + return LISTVIEW_RedrawItems (wndPtr, wParam, lParam); + +// case LVM_SCROLL: case LVM_SETBKCOLOR: return LISTVIEW_SetBkColor (wndPtr, wParam, lParam); +// case LVM_SETBKIMAGE: +// case LVM_SETCALLBACKMASK: + + case LVM_SETCOLUMN32A: + return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam); + +// case LVM_SETCOLUMN32W: +// case LVM_SETCOLUMNORDERARRAY: +// case LVM_SETCOLUMNWIDTH: +// case LVM_SETEXTENDEDLISTVIEWSTYLE: +// case LVM_SETHOTCURSOR: +// case LVM_SETHOTITEM: +// case LVM_SETHOVERTIME: +// case LVM_SETICONSPACING: case LVM_SETIMAGELIST: return LISTVIEW_SetImageList (wndPtr, wParam, lParam); -// case LVM_SETITEMPOSITION: + case LVM_SETITEM32A: + return LISTVIEW_SetItem32A (wndPtr, wParam, lParam); -// case LVM_SORTITEMS: +// case LVM_SETITEM32W: +// case LVM_SETITEMCOUNT: + + case LVM_SETITEMPOSITION: + return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam); + +// case LVM_SETITEMPOSITION32: +// case LVM_SETITEMSTATE: +// case LVM_SETITEMTEXT: +// case LVM_SETSELECTIONMARK: + + case LVM_SETTEXTBKCOLOR: + return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam); + + case LVM_SETTEXTCOLOR: + return LISTVIEW_SetTextColor (wndPtr, wParam, lParam); + +// case LVM_SETTOOLTIPS: +// case LVM_SETUNICODEFORMAT: +// case LVM_SETWORKAREAS: + + case LVM_SORTITEMS: + return LISTVIEW_SortItems (wndPtr, wParam, lParam); + +// case LVM_SUBITEMHITTEST: +// case LVM_UPDATE: + // case WM_CHAR: @@ -538,6 +1445,16 @@ return LISTVIEW_GetFont (wndPtr, wParam, lParam); // case WM_HSCROLL: +// case WM_KEYDOWN: + + case WM_KILLFOCUS: + return LISTVIEW_KillFocus (wndPtr, wParam, lParam); + + case WM_LBUTTONDBLCLK: + return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam); + + case WM_LBUTTONDOWN: + return LISTVIEW_LButtonDown (wndPtr, wParam, lParam); // case WM_MOUSEMOVE: // return LISTVIEW_MouseMove (wndPtr, wParam, lParam); @@ -548,13 +1465,20 @@ case WM_NCDESTROY: return LISTVIEW_NCDestroy (wndPtr, wParam, lParam); -// case WM_NOTIFY: + case WM_NOTIFY: + return LISTVIEW_Notify (wndPtr, wParam, lParam); case WM_PAINT: return LISTVIEW_Paint (wndPtr, wParam); -// case WM_RBUTTONDOWN: -// case WM_SETFOCUS: + case WM_RBUTTONDBLCLK: + return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam); + + case WM_RBUTTONDOWN: + return LISTVIEW_RButtonDown (wndPtr, wParam, lParam); + + case WM_SETFOCUS: + return LISTVIEW_SetFocus (wndPtr, wParam, lParam); case WM_SETFONT: return LISTVIEW_SetFont (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c index e5c231e..815a55f 100644 --- a/dlls/comctl32/pager.c +++ b/dlls/comctl32/pager.c
@@ -169,7 +169,7 @@ SetParent32 (infoPtr->hwndChild, wndPtr->hwndSelf); SetWindowPos32 (infoPtr->hwndChild, wndPtr->hwndSelf, 0, 0, 40, 40, SWP_SHOWWINDOW); - RedrawWindow32 (wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE); + RedrawWindow32 (wndPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE); return 0; }
diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index 3acb294..ad08872 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c
@@ -8,9 +8,8 @@ */ #include "windows.h" -#include "progress.h" #include "commctrl.h" -#include "heap.h" +#include "progress.h" #include "win.h" #include "debug.h" @@ -185,8 +184,7 @@ case WM_CREATE: /* allocate memory for info struct */ infoPtr = - (PROGRESS_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(PROGRESS_INFO)); + (PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; /* initialize the info struct */ @@ -200,8 +198,8 @@ break; case WM_DESTROY: - TRACE(progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd); - HeapFree (GetProcessHeap (), 0, infoPtr); + TRACE (progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd); + COMCTL32_Free (infoPtr); break; case WM_ERASEBKGND: @@ -328,11 +326,12 @@ /*********************************************************************** - * PROGRESS_Register [Internal] + * PROGRESS_Register [Internal] * * Registers the progress bar window class. * */ + void PROGRESS_Register(void) {
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index b27b5f5..2936d96 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c
@@ -16,7 +16,6 @@ #include "windows.h" #include "commctrl.h" #include "rebar.h" -#include "heap.h" #include "win.h" #include "debug.h" @@ -42,10 +41,24 @@ - - // << REBAR_BeginDrag >> -// << REBAR_DeleteBand >> + + +static LRESULT +REBAR_DeleteBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + UINT32 uBand = (UINT32)wParam; + + if (uBand >= infoPtr->uNumBands) + return FALSE; + + FIXME (rebar, "deleting band %u!\n", uBand); + + return TRUE; +} + + // << REBAR_DragMove >> // << REBAR_EndDrag >> // << REBAR_GetBandBorders >> @@ -246,16 +259,13 @@ TRACE (rebar, "insert band at %u!\n", uIndex); if (infoPtr->uNumBands == 0) { - infoPtr->bands = - (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (REBAR_BAND)); + infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND)); uIndex = 0; } else { REBAR_BAND *oldBands = infoPtr->bands; infoPtr->bands = - (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - (infoPtr->uNumBands+1)*sizeof(REBAR_BAND)); + (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND)); if (((INT32)uIndex == -1) || (uIndex > infoPtr->uNumBands)) uIndex = infoPtr->uNumBands; @@ -271,7 +281,7 @@ (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND)); } - HeapFree (GetProcessHeap (), 0, &oldBands); + COMCTL32_Free (&oldBands); } infoPtr->uNumBands++; @@ -292,8 +302,7 @@ if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { INT32 len = lstrlen32A (lprbbi->lpText); if (len > 0) { - lpBand->lpText = - (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + lpBand->lpText = (LPSTR)COMCTL32_Alloc (len + 1); lstrcpy32A (lpBand->lpText, lprbbi->lpText); } } @@ -377,8 +386,7 @@ /* INT32 len = lstrlen32A (lprbbi->lpText); if (len > 0) { - lpBand->lpText = - (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + lpBand->lpText = (LPSTR)COMCTL32_Alloc (len + 1); lstrcpy32A (lpBand->lpText, lprbbi->lpText); } */ @@ -566,13 +574,13 @@ /* delete text strings */ if (lpBand->lpText) { - HeapFree (GetProcessHeap (), 0, lpBand->lpText); + COMCTL32_Free (lpBand->lpText); lpBand->lpText = NULL; } } /* free band array */ - HeapFree (GetProcessHeap (), 0, infoPtr->bands); + COMCTL32_Free (infoPtr->bands); infoPtr->bands = NULL; } @@ -608,7 +616,10 @@ switch (uMsg) { // case RB_BEGINDRAG: -// case RB_DELETEBAND: + + case RB_DELETEBAND: + return REBAR_DeleteBand (wndPtr, wParam, lParam); + // case RB_DRAGMOVE: // case RB_ENDDRAG: // case RB_GETBANDBORDERS: @@ -621,7 +632,6 @@ case RB_GETBANDINFO32A: return REBAR_GetBandInfo32A (wndPtr, wParam, lParam); - // case RB_GETBANDINFO32W: case RB_GETBARHEIGHT:
diff --git a/dlls/comctl32/status.c b/dlls/comctl32/status.c index 6536fa9..a2c710e 100644 --- a/dlls/comctl32/status.c +++ b/dlls/comctl32/status.c
@@ -6,9 +6,8 @@ */ #include "windows.h" -#include "status.h" #include "commctrl.h" -#include "heap.h" +#include "status.h" #include "win.h" #include "debug.h" @@ -528,17 +527,16 @@ if (oldNumParts > self->numParts) { for (i = self->numParts ; i < oldNumParts; i++) { if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW)) - HeapFree(GetProcessHeap (), 0, self->parts[i].text); + COMCTL32_Free (self->parts[i].text); } } else if (oldNumParts < self->numParts) { - tmp = HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(STATUSWINDOWPART) * self->numParts); + tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts); for (i = 0; i < oldNumParts; i++) { tmp[i] = self->parts[i]; } if (self->parts) - HeapFree(GetProcessHeap (), 0, self->parts); + COMCTL32_Free (self->parts); self->parts = tmp; } @@ -614,10 +612,10 @@ else { /* duplicate string */ if (part->text) - HeapFree (GetProcessHeap (), 0, part->text); + COMCTL32_Free (part->text); part->text = 0; if (text && (len = lstrlen32A(text))) { - part->text = HeapAlloc (GetProcessHeap (), 0, len+1); + part->text = COMCTL32_Alloc (len+1); lstrcpy32A(part->text, text); } } @@ -694,8 +692,7 @@ HDC32 hdc; STATUSWINDOWINFO *self; - self = (STATUSWINDOWINFO*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(STATUSWINDOWINFO)); + self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO)); wndPtr->wExtra[0] = (DWORD)self; self->numParts = 1; @@ -717,8 +714,7 @@ self->part0.hIcon = 0; /* initialize first part */ - self->parts = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(STATUSWINDOWPART)); + self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART)); self->parts[0].bound = rect; self->parts[0].text = 0; self->parts[0].x = -1; @@ -726,7 +722,7 @@ self->parts[0].hIcon = 0; if ((len = lstrlen32A (lpCreate->lpszName))) { - self->parts[0].text = HeapAlloc (GetProcessHeap (), 0, len + 1); + self->parts[0].text = COMCTL32_Alloc (len + 1); lstrcpy32A (self->parts[0].text, lpCreate->lpszName); } @@ -781,11 +777,11 @@ for (i = 0; i < self->numParts; i++) { if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW)) - HeapFree(GetProcessHeap (), 0, self->parts[i].text); + COMCTL32_Free (self->parts[i].text); } if (self->part0.text && (self->part0.style != SBT_OWNERDRAW)) - HeapFree(GetProcessHeap (), 0, self->part0.text); - HeapFree(GetProcessHeap (), 0, self->parts); + COMCTL32_Free (self->part0.text); + COMCTL32_Free (self->parts); /* delete default font */ if (self->hDefaultFont) @@ -795,7 +791,7 @@ if (self->hwndToolTip) DestroyWindow32 (self->hwndToolTip); - HeapFree(GetProcessHeap (), 0, self); + COMCTL32_Free (self); return 0; } @@ -939,10 +935,10 @@ part = &self->parts[0]; /* duplicate string */ if (part->text) - HeapFree(GetProcessHeap (), 0, part->text); + COMCTL32_Free (part->text); part->text = 0; if (lParam && (len = lstrlen32A((LPCSTR)lParam))) { - part->text = HeapAlloc (GetProcessHeap (), 0, len+1); + part->text = COMCTL32_Alloc (len+1); lstrcpy32A (part->text, (LPCSTR)lParam); }
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index a1ac4e3..2a89d4b 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c
@@ -4,11 +4,9 @@ * Copyright 1998 Eric Kohl * * TODO: - * - Bitmap drawing. * - Button wrapping. * - Messages. * - Notifications. - * - Fix TB_GETBITMAPFLAGS. * - Fix TB_GETROWS and TB_SETROWS. * - Tooltip support (almost complete). * - Unicode suppport. @@ -27,11 +25,10 @@ */ #include "windows.h" -#include "sysmetrics.h" #include "commctrl.h" +#include "sysmetrics.h" #include "cache.h" #include "toolbar.h" -#include "heap.h" #include "win.h" #include "debug.h" @@ -67,13 +64,13 @@ TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC32 hdc, INT32 nState) { - RECT32 rcText = btnPtr->rect; - HFONT32 hOldFont; - INT32 nOldBkMode; + RECT32 rcText = btnPtr->rect; + HFONT32 hOldFont; + INT32 nOldBkMode; + COLORREF clrOld; /* draw text */ if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) { - InflateRect32 (&rcText, -3, -3); rcText.top += infoPtr->nBitmapHeight; if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED)) @@ -82,28 +79,27 @@ hOldFont = SelectObject32 (hdc, infoPtr->hFont); nOldBkMode = SetBkMode32 (hdc, TRANSPARENT); if (!(nState & TBSTATE_ENABLED)) { - COLORREF clrOld = - SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT)); + clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT)); OffsetRect32 (&rcText, 1, 1); - DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText, - DT_CENTER); + DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, + &rcText, infoPtr->dwDTFlags); SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW)); OffsetRect32 (&rcText, -1, -1); - DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText, - DT_CENTER); - SetTextColor32 (hdc, clrOld); + DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, + &rcText, infoPtr->dwDTFlags); } else if (nState & TBSTATE_INDETERMINATE) { - COLORREF clrOld = - SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW)); - DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText, - DT_CENTER); - SetTextColor32 (hdc, clrOld); + clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW)); + DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, + &rcText, infoPtr->dwDTFlags); } - else - DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, &rcText, - DT_CENTER); + else { + clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT)); + DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1, + &rcText, infoPtr->dwDTFlags); + } + SetTextColor32 (hdc, clrOld); SelectObject32 (hdc, hOldFont); if (nOldBkMode != TRANSPARENT) SetBkMode32 (hdc, nOldBkMode); @@ -112,6 +108,46 @@ static void +TOOLBAR_DrawPattern (HDC32 hdc, LPRECT32 lpRect) +{ + HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ()); + INT32 cx = lpRect->right - lpRect->left; + INT32 cy = lpRect->bottom - lpRect->top; + PatBlt32 (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089); + SelectObject32 (hdc, hbr); +} + + +static void +TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, + HDC32 hdc, INT32 x, INT32 y) +{ + /* FIXME: this function is a hack since it uses image list + internals directly */ + + HDC32 hdcImageList = CreateCompatibleDC32 (0); + HIMAGELIST himl = infoPtr->himlDef; + + /* draw the mask */ + SelectObject32 (hdcImageList, himl->hbmMask); + SetBkColor32 (hdcImageList, RGB(255, 255, 255)); + SetTextColor32 (hdcImageList, RGB(0, 0, 0)); + + SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DHILIGHT)); + BitBlt32 (hdc, x+1, y+1, himl->cx, himl->cy, + hdcImageList, himl->cx * btnPtr->iBitmap, 0, + 0xB8074A); + + SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DSHADOW)); + BitBlt32 (hdc, x, y, himl->cx, himl->cy, + hdcImageList, himl->cx * btnPtr->iBitmap, 0, + 0xB8074A); + + DeleteDC32 (hdcImageList); +} + + +static void TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); @@ -129,12 +165,11 @@ /* disabled */ if (!(btnPtr->fsState & TBSTATE_ENABLED)) { - HICON32 hIcon; DrawEdge32 (hdc, &rc, EDGE_RAISED, BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST); -// ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc, -// rc.left+1, rc.top+1, ILD_NORMAL); + TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState); return; } @@ -152,7 +187,6 @@ /* checked TBSTYLE_CHECK*/ if ((btnPtr->fsStyle & TBSTYLE_CHECK) && (btnPtr->fsState & TBSTATE_CHECKED)) { - HBRUSH32 hbr; if (bFlat) DrawEdge32 (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST); @@ -160,10 +194,7 @@ DrawEdge32 (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST); - hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ()); - PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left, - rc.bottom - rc.top, 0x00FA0089); - SelectObject32 (hdc, hbr); + TOOLBAR_DrawPattern (hdc, &rc); ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc, rc.left+2, rc.top+2, ILD_NORMAL); TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState); @@ -172,16 +203,11 @@ /* indeterminate */ if (btnPtr->fsState & TBSTATE_INDETERMINATE) { - HBRUSH32 hbr; DrawEdge32 (hdc, &rc, EDGE_RAISED, BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST); - hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ()); - PatBlt32 (hdc, rc.left, rc.top, rc.right - rc.left, - rc.bottom - rc.top, 0x00FA0089); - SelectObject32 (hdc, hbr); -// ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc, -// rc.left+1, rc.top+1, ILD_NORMAL); + TOOLBAR_DrawPattern (hdc, &rc); + TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState); return; } @@ -495,7 +521,7 @@ if (lpAddBmp->hInst == (HINSTANCE32)0) { nIndex = ImageList_AddMasked (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID, - GetSysColor32 (COLOR_3DFACE)); + CLR_DEFAULT); } else if (lpAddBmp->hInst == HINST_COMMCTRL) { /* add internal bitmaps */ @@ -510,7 +536,7 @@ HBITMAP32 hBmp = LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID); - nIndex = ImageList_Add (infoPtr->himlDef, hBmp, (HBITMAP32)0); + nIndex = ImageList_AddMasked (infoPtr->himlDef, hBmp, CLR_DEFAULT); DeleteObject32 (hBmp); } @@ -538,17 +564,15 @@ if (infoPtr->nNumButtons == 0) { infoPtr->buttons = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (TBUTTON_INFO) * nNewButtons); + COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons); } else { TBUTTON_INFO *oldButtons = infoPtr->buttons; infoPtr->buttons = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (TBUTTON_INFO) * nNewButtons); + COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons); memcpy (&infoPtr->buttons[0], &oldButtons[0], nOldButtons * sizeof(TBUTTON_INFO)); - HeapFree (GetProcessHeap (), 0, oldButtons); + COMCTL32_Free (oldButtons); } infoPtr->nNumButtons = nNewButtons; @@ -609,20 +633,19 @@ nIndex = infoPtr->nNumStrings; if (infoPtr->nNumStrings == 0) { infoPtr->strings = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char *)); + COMCTL32_Alloc (sizeof(char *)); } else { char **oldStrings = infoPtr->strings; infoPtr->strings = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(char *) * (infoPtr->nNumStrings + 1)); + COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1)); memcpy (&infoPtr->strings[0], &oldStrings[0], sizeof(char *) * infoPtr->nNumStrings); - HeapFree (GetProcessHeap (), 0, oldStrings); + COMCTL32_Free (oldStrings); } infoPtr->strings[infoPtr->nNumStrings] = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1)); + COMCTL32_Alloc (sizeof(char)*(len+1)); lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], szString); infoPtr->nNumStrings++; } @@ -639,20 +662,19 @@ if (infoPtr->nNumStrings == 0) { infoPtr->strings = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char *)); + COMCTL32_Alloc (sizeof(char *)); } else { char **oldStrings = infoPtr->strings; infoPtr->strings = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(char *) * (infoPtr->nNumStrings + 1)); + COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1)); memcpy (&infoPtr->strings[0], &oldStrings[0], sizeof(char *) * infoPtr->nNumStrings); - HeapFree (GetProcessHeap (), 0, oldStrings); + COMCTL32_Free (oldStrings); } infoPtr->strings[infoPtr->nNumStrings] = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1)); + COMCTL32_Alloc (sizeof(char)*(len+1)); lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], p); infoPtr->nNumStrings++; @@ -841,7 +863,7 @@ if (infoPtr->nNumButtons == 1) { TRACE (toolbar, " simple delete!\n"); - HeapFree (GetProcessHeap (), 0, infoPtr->buttons); + COMCTL32_Free (infoPtr->buttons); infoPtr->buttons = NULL; infoPtr->nNumButtons = 0; } @@ -850,8 +872,7 @@ TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex); infoPtr->nNumButtons--; - infoPtr->buttons = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (TBUTTON_INFO) * infoPtr->nNumButtons); + infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons); if (nIndex > 0) { memcpy (&infoPtr->buttons[0], &oldButtons[0], nIndex * sizeof(TBUTTON_INFO)); @@ -862,7 +883,7 @@ (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO)); } - HeapFree (GetProcessHeap (), 0, oldButtons); + COMCTL32_Free (oldButtons); } TOOLBAR_CalcToolbar (wndPtr); @@ -911,17 +932,16 @@ nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam); if (nIndex == -1) - return 0; + return -1; return infoPtr->buttons[nIndex].iBitmap; } -static LRESULT +static __inline__ LRESULT TOOLBAR_GetBitmapFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { - FIXME (toolbar, "stub!\n"); - return 0; + return (GetDeviceCaps32 (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0; } @@ -1312,8 +1332,7 @@ oldButtons = infoPtr->buttons; infoPtr->nNumButtons++; - infoPtr->buttons = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof (TBUTTON_INFO) * infoPtr->nNumButtons); + infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons); /* pre insert copy */ if (nIndex > 0) { memcpy (&infoPtr->buttons[0], &oldButtons[0], @@ -1348,7 +1367,7 @@ (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO)); } - HeapFree (GetProcessHeap (), 0, oldButtons); + COMCTL32_Free (oldButtons); TOOLBAR_CalcToolbar (wndPtr); @@ -1486,6 +1505,7 @@ static LRESULT TOOLBAR_SaveRestore32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { +#if 0 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); LPTBSAVEPARAMS32A lpSave = (LPTBSAVEPARAMS32A)lParam; @@ -1506,6 +1526,7 @@ } +#endif return 0; } @@ -1565,13 +1586,13 @@ if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings)) { #if 0 - CHAR *lpString = infoPtr->strings[btnPtr->iString]; + CHAR **lpString = &infoPtr->strings[btnPtr->iString]; INT32 len = lstrlen32A (lptbbi->pszText); - - lpString = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(char)*(len+1)); - + *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1)); #endif + /* this is the ultimate sollution */ +// Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); } } @@ -1654,7 +1675,18 @@ } -// << TOOLBAR_SetDrawTextFlags >> +static LRESULT +TOOLBAR_SetDrawTextFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + DWORD dwTemp; + + dwTemp = infoPtr->dwDTFlags; + infoPtr->dwDTFlags = + (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam; + + return (LRESULT)dwTemp; +} static LRESULT @@ -1910,6 +1942,7 @@ infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf); infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT); infoPtr->nHotItem = -1; + infoPtr->dwDTFlags = DT_CENTER; SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0); infoPtr->hFont = CreateFontIndirect32A (&logFont); @@ -1951,16 +1984,16 @@ /* delete button data */ if (infoPtr->buttons) - HeapFree (GetProcessHeap (), 0, infoPtr->buttons); + COMCTL32_Free (infoPtr->buttons); /* delete strings */ if (infoPtr->strings) { INT32 i; for (i = 0; i < infoPtr->nNumStrings; i++) if (infoPtr->strings[i]) - HeapFree (GetProcessHeap (), 0, infoPtr->strings[i]); + COMCTL32_Free (infoPtr->strings[i]); - HeapFree (GetProcessHeap (), 0, infoPtr->strings); + COMCTL32_Free (infoPtr->strings); } /* destroy default image list */ @@ -1980,7 +2013,7 @@ DeleteObject32 (infoPtr->hFont); /* free toolbar info data */ - HeapFree (GetProcessHeap (), 0, infoPtr); + COMCTL32_Free (infoPtr); return 0; } @@ -2178,7 +2211,15 @@ } -// << TOOLBAR_NCActivate >> +__inline__ static LRESULT +TOOLBAR_NCActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ +// if (wndPtr->dwStyle & CCS_NODIVIDER) + return DefWindowProc32A (wndPtr->hwndSelf, WM_NCACTIVATE, + wParam, lParam); +// else +// return TOOLBAR_NCPaint (wndPtr, wParam, lParam); +} __inline__ static LRESULT @@ -2197,8 +2238,7 @@ TOOLBAR_INFO *infoPtr; /* allocate memory for info structure */ - infoPtr = (TOOLBAR_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TOOLBAR_INFO)); + infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; if (infoPtr == NULL) { @@ -2568,7 +2608,8 @@ case TB_SETDISABLEDIMAGELIST: return TOOLBAR_SetDisabledImageList (wndPtr, wParam, lParam); -// case TB_SETDRAWTEXTFLAGS: /* 4.71 */ + case TB_SETDRAWTEXTFLAGS: + return TOOLBAR_SetDrawTextFlags (wndPtr, wParam, lParam); case TB_SETEXTENDEDSTYLE: return TOOLBAR_SetExtendedStyle (wndPtr, wParam, lParam); @@ -2640,8 +2681,8 @@ case WM_MOUSEMOVE: return TOOLBAR_MouseMove (wndPtr, wParam, lParam); -// case WM_NCACTIVATE: -// return TOOLBAR_NCActivate (wndPtr, wParam, lParam); + case WM_NCACTIVATE: + return TOOLBAR_NCActivate (wndPtr, wParam, lParam); case WM_NCCALCSIZE: return TOOLBAR_NCCalcSize (wndPtr, wParam, lParam);
diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 93ea5f3..419f605 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c
@@ -21,7 +21,6 @@ #include "windows.h" #include "commctrl.h" #include "tooltips.h" -#include "heap.h" #include "win.h" #include "debug.h" @@ -108,8 +107,7 @@ if (ttnmdi.uFlags & TTF_DI_SETITEM) { INT32 len = lstrlen32A (ttnmdi.szText) + 1; toolPtr->hinst = 0; - toolPtr->lpszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len); + toolPtr->lpszText = COMCTL32_Alloc (len); lstrcpy32A (toolPtr->lpszText, ttnmdi.szText); } } @@ -124,8 +122,7 @@ if (ttnmdi.uFlags & TTF_DI_SETITEM) { INT32 len = lstrlen32A (ttnmdi.lpszText) + 1; toolPtr->hinst = 0; - toolPtr->lpszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len); + toolPtr->lpszText = COMCTL32_Alloc (len); lstrcpy32A (toolPtr->lpszText, ttnmdi.lpszText); } } @@ -177,7 +174,7 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr) { TTTOOL_INFO *toolPtr; - POINT32 pt; + RECT32 rect; SIZE32 size; NMHDR hdr; @@ -212,31 +209,37 @@ TRACE (tooltips, "size %d - %d\n", size.cx, size.cy); if ((toolPtr->uFlags & TTF_TRACK) && (toolPtr->uFlags & TTF_ABSOLUTE)) { - pt.x = infoPtr->xTrackPos; - pt.y = infoPtr->yTrackPos; + rect.left = infoPtr->xTrackPos; + rect.top = infoPtr->yTrackPos; } else if (toolPtr->uFlags & TTF_CENTERTIP) { - RECT32 rect; + RECT32 rc; if (toolPtr->uFlags & TTF_IDISHWND) - GetWindowRect32 ((HWND32)toolPtr->uId, &rect); + GetWindowRect32 ((HWND32)toolPtr->uId, &rc); else { - rect = toolPtr->rect; - MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rect, 2); + rc = toolPtr->rect; + MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rc, 2); } - pt.x = (rect.left + rect.right - size.cx) / 2; - pt.y = rect.bottom + 2; + rect.left = (rc.left + rc.right - size.cx) / 2; + rect.top = rc.bottom + 2; } else { - GetCursorPos32 (&pt); - pt.y += 20; + GetCursorPos32 ((LPPOINT32)&rect); + rect.top += 20; } - TRACE (tooltips, "pos %d - %d\n", pt.x, pt.y); + TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top); + + rect.right = rect.left + size.cx; + rect.bottom = rect.top + size.cy; + + AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle); // SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1, - SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y, - size.cx, size.cy, SWP_SHOWWINDOW); + SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_SHOWWINDOW); SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0); } @@ -263,7 +266,8 @@ infoPtr->nCurrentTool = -1; - SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW); + SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, + SWP_NOZORDER | SWP_HIDEWINDOW); } @@ -406,19 +410,16 @@ (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : ""); if (infoPtr->uNumTools == 0) { - infoPtr->tools = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TTTOOL_INFO)); + infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO)); toolPtr = infoPtr->tools; } else { TTTOOL_INFO *oldTools = infoPtr->tools; infoPtr->tools = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1)); + COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1)); memcpy (infoPtr->tools, oldTools, infoPtr->uNumTools * sizeof(TTTOOL_INFO)); - HeapFree (GetProcessHeap (), 0, oldTools); + COMCTL32_Free (oldTools); toolPtr = &infoPtr->tools[infoPtr->uNumTools]; } @@ -443,8 +444,7 @@ else { INT32 len = lstrlen32A (lpToolInfo->lpszText); TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText); - toolPtr->lpszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + toolPtr->lpszText = COMCTL32_Alloc (len + 1); lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText); } } @@ -458,8 +458,8 @@ LPTT_SUBCLASS_INFO lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); if (lpttsi == NULL) { - lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(), - HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO)); + lpttsi = + (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO)); lpttsi->wpOrigProc = (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc); @@ -475,8 +475,8 @@ LPTT_SUBCLASS_INFO lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP); if (lpttsi == NULL) { - lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(), - HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO)); + lpttsi = + (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO)); lpttsi->wpOrigProc = (WNDPROC32)SetWindowLong32A (toolPtr->hwnd, GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc); @@ -521,7 +521,7 @@ toolPtr = &infoPtr->tools[nTool]; if ((toolPtr->hinst) && (toolPtr->lpszText)) { if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A) - HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); + COMCTL32_Free (toolPtr->lpszText); } /* remove subclassing */ @@ -533,7 +533,7 @@ SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, (LONG)lpttsi->wpOrigProc); RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); - HeapFree (GetProcessHeap(), 0, &lpttsi); + COMCTL32_Free (&lpttsi); } else ERR (tooltips, "Invalid data handle!\n"); @@ -546,7 +546,7 @@ SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, (LONG)lpttsi->wpOrigProc); RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); - HeapFree (GetProcessHeap(), 0, &lpttsi); + COMCTL32_Free (&lpttsi); } else lpttsi->uRefCount--; @@ -558,14 +558,13 @@ /* delete tool from tool list */ if (infoPtr->uNumTools == 1) { - HeapFree (GetProcessHeap (), 0, infoPtr->tools); + COMCTL32_Free (infoPtr->tools); infoPtr->tools = NULL; } else { TTTOOL_INFO *oldTools = infoPtr->tools; infoPtr->tools = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1)); + COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1)); if (nTool > 0) memcpy (&infoPtr->tools[0], &oldTools[0], @@ -575,7 +574,7 @@ memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1], (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO)); - HeapFree (GetProcessHeap (), 0, oldTools); + COMCTL32_Free (oldTools); } infoPtr->uNumTools--; @@ -1051,9 +1050,8 @@ toolPtr->lpszText = lpToolInfo->lpszText; else { INT32 len = lstrlen32A (lpToolInfo->lpszText); - HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); - toolPtr->lpszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + COMCTL32_Free (toolPtr->lpszText); + toolPtr->lpszText = COMCTL32_Alloc (len + 1); lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText); } } @@ -1160,9 +1158,8 @@ toolPtr->lpszText = lpToolInfo->lpszText; else { INT32 len = lstrlen32A (lpToolInfo->lpszText); - HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); - toolPtr->lpszText = - HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + COMCTL32_Free (toolPtr->lpszText); + toolPtr->lpszText = COMCTL32_Alloc (len + 1); lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText); } } @@ -1189,8 +1186,7 @@ NONCLIENTMETRICS32A nclm; /* allocate memory for info structure */ - infoPtr = (TOOLTIPS_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TOOLTIPS_INFO)); + infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; if (infoPtr == NULL) { @@ -1219,7 +1215,8 @@ infoPtr->nAutoPopTime = 5000; infoPtr->nInitialTime = 500; - SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW); + SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, + SWP_NOZORDER | SWP_HIDEWINDOW); return 0; } @@ -1230,15 +1227,15 @@ { TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr); TTTOOL_INFO *toolPtr; + INT32 i; /* free tools */ if (infoPtr->tools) { - INT32 i; for (i = 0; i < infoPtr->uNumTools; i++) { toolPtr = &infoPtr->tools[i]; if ((toolPtr->hinst) && (toolPtr->lpszText)) { if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A) - HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); + COMCTL32_Free (toolPtr->lpszText); } /* remove subclassing */ @@ -1254,18 +1251,18 @@ SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, (LONG)lpttsi->wpOrigProc); RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); - HeapFree (GetProcessHeap(), 0, &lpttsi); + COMCTL32_Free (&lpttsi); } } } - HeapFree (GetProcessHeap (), 0, infoPtr->tools); + COMCTL32_Free (infoPtr->tools); } /* delete font */ DeleteObject32 (infoPtr->hFont); /* free tool tips info data */ - HeapFree (GetProcessHeap (), 0, infoPtr); + COMCTL32_Free (infoPtr); return 0; } @@ -1327,7 +1324,10 @@ TOOLTIPS_NcCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { wndPtr->dwStyle &= 0x0000FFFF; - wndPtr->dwStyle |= (WS_POPUP | WS_BORDER); + wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS); + +// FIXME (tooltips, "style 0x%08x\n", wndPtr->dwStyle); +// SetParent32 (wndPtr->hwndSelf, NULL); return TRUE; }
diff --git a/dlls/comctl32/trackbar.c b/dlls/comctl32/trackbar.c index f80f433..6470916 100644 --- a/dlls/comctl32/trackbar.c +++ b/dlls/comctl32/trackbar.c
@@ -1,21 +1,31 @@ /* * Trackbar control * - * Copyright 1998 Eric Kohl + * Copyright 1998 Eric Kohli <ekohl@abo.rhein-zeitung.de> + * Copyright 1998 Alex Priem <alexp@sci.kun.nl> * * NOTES - * Development in progress. Author needed! Any volunteers? - * I will only improve this control once in a while. - * Eric <ekohl@abo.rhein-zeitung.de> + * * TODO: * - Some messages. - * - display code. - * - user interaction. - * - tic handling. - * - All notifications. + * - more display code. + * - dragging slider + * - better tic handling. + * - more notifications. + * - tooltips */ +/* known bugs: + + -TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the + trackbar, not the actual amount of tics in the list. + -TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted. + -code currently only handles horizontal trackbars correct. +*/ + + + #include "windows.h" #include "commctrl.h" #include "trackbar.h" @@ -27,88 +37,303 @@ #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)wndPtr->wExtra[0]) -static VOID -TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc) +/* Used by TRACKBAR_Refresh to find out which parts of the control + need to be recalculated */ + +#define TB_THUMBCHANGED 1 +#define TB_SELECTIONCHANGED 2 + + + +static BOOL32 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code); + +void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr) + { - TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - RECT32 rcClient, rcChannel; + int i,tic,nrTics; - GetClientRect32 (wndPtr->hwndSelf, &rcClient); + if (infoPtr->uTicFreq) + nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq; + else { + nrTics=0; + HeapFree (SystemHeap,0,infoPtr->tics); + infoPtr->tics=NULL; + infoPtr->uNumTics=0; + return; + } - /* draw channel */ - rcChannel = infoPtr->rcChannel; - DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - if (wndPtr->dwStyle & TBS_ENABLESELRANGE) { - /* fill the channel */ - HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255)); - FillRect32 (hdc, &rcChannel, hbr); - DeleteObject32 (hbr); + if (nrTics!=infoPtr->uNumTics) { + infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics, + (nrTics+1)*sizeof (DWORD)); + infoPtr->uNumTics=nrTics; } - - /* draw ticks */ - if (!(wndPtr->dwStyle & TBS_NOTICKS)) { - - } - - /* draw thumb */ - if (!(wndPtr->dwStyle & TBS_NOTHUMB)) { - - } - - if (infoPtr->bFocus) - DrawFocusRect32 (hdc, &rcClient); + infoPtr->uNumTics=nrTics; + tic=infoPtr->nRangeMin+infoPtr->uTicFreq; + for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq) + infoPtr->tics[i]=tic; } + +static INT32 +TRACKBAR_ConvertPositionToTic (WND *wndPtr, TRACKBAR_INFO *infoPtr, POINT32 pt) +{ + double newpos,newtic; + int i,range,width,delta,currentdelta,currenttic; + +/* buggy */ + + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=infoPtr->rcChannel.right - infoPtr->rcChannel.left; + + newpos=(pt.x-infoPtr->rcChannel.left) / (double) width; + + newtic=infoPtr->nRangeMin+newpos*range; + currenttic=0; + currentdelta=currenttic-infoPtr->nRangeMin; + for (i=0; i<infoPtr->uNumTics; i++) { + delta=newtic-infoPtr->tics[i]; + if ((delta>0) && (delta<currentdelta)) { + currentdelta=delta; + currenttic=i; + } + } + return (INT32) currenttic; +} + static VOID -TRACKBAR_Calc (WND *wndPtr, TRACKBAR_INFO *infoPtr, LPRECT32 lpRect) +TRACKBAR_Calc (WND *wndPtr, TRACKBAR_INFO *infoPtr) { INT32 cyChannel; + RECT32 lpRect,*channel = & infoPtr->rcChannel; + + GetClientRect32 (wndPtr->hwndSelf, &lpRect); if (wndPtr->dwStyle & TBS_ENABLESELRANGE) - cyChannel = MAX(infoPtr->uThumbLen - 8, 4); + cyChannel = MAX(infoPtr->uThumbLen - 8, 4); else - cyChannel = 4; + cyChannel = 4; /* calculate channel rect */ if (wndPtr->dwStyle & TBS_VERT) { - infoPtr->rcChannel.top = lpRect->top + 8; - infoPtr->rcChannel.bottom = lpRect->bottom - 8; + channel->top = lpRect.top + 8; + channel->bottom = lpRect.bottom - 8; - if (wndPtr->dwStyle & TBS_BOTH) { - infoPtr->rcChannel.left = (lpRect->bottom - cyChannel ) / 2; - infoPtr->rcChannel.right = (lpRect->bottom + cyChannel) / 2; + if (wndPtr->dwStyle & TBS_BOTH) { + channel->left = (lpRect.bottom - cyChannel) / 2; + channel->right = (lpRect.bottom + cyChannel) / 2; + } + else if (wndPtr->dwStyle & TBS_LEFT) { + channel->left = lpRect.left + 10; + channel->right = channel->left + cyChannel; + } + else { /* TBS_RIGHT */ + channel->right = lpRect.right - 10; + channel->left = channel->right - cyChannel; + } + } + else { + channel->left = lpRect.left + 8; + channel->right = lpRect.right - 8; + if (wndPtr->dwStyle & TBS_BOTH) { + channel->top = (lpRect.bottom - cyChannel) / 2; + channel->bottom = (lpRect.bottom + cyChannel) / 2; + } + else if (wndPtr->dwStyle & TBS_TOP) { + channel->top = lpRect.top + 10; + channel->bottom = channel->top + cyChannel; + } + else { /* TBS_BOTTOM */ + channel->bottom = lpRect.bottom - 10; + channel->top = channel->bottom - cyChannel; + } } - else if (wndPtr->dwStyle & TBS_LEFT) { - infoPtr->rcChannel.left = lpRect->left + 10; - infoPtr->rcChannel.right = infoPtr->rcChannel.left + cyChannel; - } - else { - /* TBS_RIGHT */ - infoPtr->rcChannel.right = lpRect->right - 10; - infoPtr->rcChannel.left = infoPtr->rcChannel.right - cyChannel; - } - } - else { - infoPtr->rcChannel.left = lpRect->left + 8; - infoPtr->rcChannel.right = lpRect->right - 8; - - if (wndPtr->dwStyle & TBS_BOTH) { - infoPtr->rcChannel.top = (lpRect->bottom - cyChannel ) / 2; - infoPtr->rcChannel.bottom = (lpRect->bottom + cyChannel) / 2; - } - else if (wndPtr->dwStyle & TBS_TOP) { - infoPtr->rcChannel.top = lpRect->top + 10; - infoPtr->rcChannel.bottom = infoPtr->rcChannel.top + cyChannel; - } - else { - /* TBS_BOTTOM */ - infoPtr->rcChannel.bottom = lpRect->bottom - 10; - infoPtr->rcChannel.top = infoPtr->rcChannel.bottom - cyChannel; - } - } } +static VOID +TRACKBAR_CalcThumb (WND *wndPtr, TRACKBAR_INFO *infoPtr) + +{ + RECT32 *thumb; + int range, width; + + thumb=&infoPtr->rcThumb; + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=infoPtr->rcChannel.right - infoPtr->rcChannel.left; + + thumb->left = infoPtr->rcChannel.left + + width*(65536*infoPtr->nPos/range)/65536 - 5; + thumb->right = thumb->left + 10; + thumb->top = infoPtr->rcChannel.top - 1; + thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8; +} + +static VOID +TRACKBAR_CalcSelection (WND *wndPtr, TRACKBAR_INFO *infoPtr) +{ + RECT32 *selection; + int range, width; + + selection= & infoPtr->rcSelection; + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=infoPtr->rcChannel.right - infoPtr->rcChannel.left; + + selection->left = infoPtr->rcChannel.left + + width*(65536*infoPtr->nSelMin/range)/65536; + selection->right = infoPtr->rcChannel.left + + width*(65536*infoPtr->nSelMax/range)/65536; + selection->top = infoPtr->rcChannel.top + 2; + selection->bottom = infoPtr->rcChannel.bottom - 2; +} + + + +static VOID +TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + RECT32 rcClient, rcChannel, rcSelection; + HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk); + INT32 x,y,tic; + int i,range,width; + + GetClientRect32 (wndPtr->hwndSelf, &rcClient); + hBrush = CreateSolidBrush32 (infoPtr->clrBk); + FillRect32 (hdc, &rcClient, hBrush); + DeleteObject32 (hBrush); + + + + if (infoPtr->flags & TB_THUMBCHANGED) + TRACKBAR_CalcThumb (wndPtr, infoPtr); + if (infoPtr->flags & TB_SELECTIONCHANGED) + TRACKBAR_CalcSelection (wndPtr, infoPtr); + infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED); + + /* draw channel */ + + rcChannel = infoPtr->rcChannel; + rcSelection= infoPtr->rcSelection; + DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + + if (wndPtr->dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */ + HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255)); + FillRect32 (hdc, &rcChannel, hbr); + if (rcSelection.left!=rcSelection.right) { + hbr=CreateSolidBrush32 (COLOR_HIGHLIGHT); + FillRect32 (hdc, &rcSelection, hbr); + } + DeleteObject32 (hbr); + } + + + /* draw tics */ + + if (!(wndPtr->dwStyle & TBS_NOTICKS)) { + COLORREF clrTic=GetSysColor32 (COLOR_3DDKSHADOW); + + x=rcChannel.left; + y=rcChannel.bottom+2; + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=rcChannel.right - rcChannel.left; + if (wndPtr->dwStyle & TBS_VERT) { /* swap x/y */ + } + + if ((wndPtr->dwStyle & TBS_TOP) || (wndPtr->dwStyle & TBS_BOTH)) { + /* draw upper tics */ + } + +// if (!((wndPtr->dwStyle & TBS_TOP) || (!(wndPtr->dwStyle & TBS_BOTH)))) + /* draw lower tics */ +// if (wndPtr->dwStyle & TBS_AUTOTICKS) + for (i=0; i<infoPtr->uNumTics; i++) { + tic=infoPtr->tics[i]; + if ((tic>infoPtr->nRangeMin) && (tic<infoPtr->nRangeMax)) { + x=rcChannel.left + width*(65536*tic/range)/65536; + SetPixel32 (hdc, x,y+5, clrTic); + SetPixel32 (hdc, x,y+6, clrTic); + SetPixel32 (hdc, x,y+7, clrTic); + } + } + if ((wndPtr->dwStyle & TBS_ENABLESELRANGE) && + (rcSelection.left!=rcSelection.right)) { + x=rcChannel.left + width*(65536*infoPtr->nSelMin/range)/65536 - 1; + SetPixel32 (hdc, x,y+6, clrTic); + SetPixel32 (hdc, x,y+7, clrTic); + x=rcChannel.left + width*(65536*infoPtr->nSelMax/range)/65536 + 1; + SetPixel32 (hdc, x,y+6, clrTic); + SetPixel32 (hdc, x,y+7, clrTic); + } + + x=rcChannel.left; + SetPixel32 (hdc, x,y+5, clrTic); + SetPixel32 (hdc, x,y+6, clrTic); + SetPixel32 (hdc, x,y+7, clrTic); + SetPixel32 (hdc, x,y+8, clrTic); + x=rcChannel.right; + SetPixel32 (hdc, x,y+5, clrTic); + SetPixel32 (hdc, x,y+6, clrTic); + SetPixel32 (hdc, x,y+7, clrTic); + SetPixel32 (hdc, x,y+8, clrTic); +// } + } + + + /* draw thumb */ + + if (!(wndPtr->dwStyle & TBS_NOTHUMB)) { + HBRUSH32 hbr = CreateSolidBrush32 (COLOR_BACKGROUND); + RECT32 thumb = infoPtr->rcThumb; + + SelectObject32 (hdc, hbr); + + if (wndPtr->dwStyle & TBS_BOTH) { + FillRect32 (hdc, &thumb, hbr); + DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT); + } else { + + POINT32 points[6]; + RECT32 triangle; /* for correct shadows of thumb */ + + /* first, fill the thumb */ + + SetPolyFillMode32 (hdc,WINDING); + points[0].x=thumb.left; + points[0].y=thumb.top; + points[1].x=thumb.right - 1; + points[1].y=thumb.top; + points[2].x=thumb.right - 1; + points[2].y=thumb.bottom -2; + points[3].x=(thumb.right + thumb.left-1)/2; + points[3].y=thumb.bottom+4; + points[4].x=thumb.left; + points[4].y=thumb.bottom -2; + points[5].x=points[0].x; + points[5].y=points[0].y; + Polygon32 (hdc, points, 6); + DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT); +// DrawEdge32 (hdc, &thumb, EDGE_SUNKEN, BF_BOTTOMRIGHT); + + /* draw notch */ + + triangle.right = thumb.right+5; + triangle.left = points[3].x+5; + triangle.top = thumb.bottom +5; + triangle.bottom= thumb.bottom +1; + DrawEdge32 (hdc, &triangle, EDGE_SUNKEN, BF_DIAGONAL | BF_TOP | BF_RIGHT); + triangle.left = thumb.left+6; + triangle.right = points[3].x+6; + DrawEdge32 (hdc, &triangle, EDGE_RAISED, BF_DIAGONAL | BF_TOP | BF_LEFT); + } + DeleteObject32 (hbr); + } + + if (infoPtr->bFocus) + DrawFocusRect32 (hdc, &rcClient); +} + + + static VOID TRACKBAR_AlignBuddies (WND *wndPtr, TRACKBAR_INFO *infoPtr) @@ -169,11 +394,12 @@ infoPtr->nSelMin = 0; infoPtr->nSelMax = 0; + infoPtr->flags |=TB_SELECTIONCHANGED; if ((BOOL32)wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -186,16 +412,15 @@ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); if (infoPtr->tics) { - FIXME (trackbar, "is this correct??\n"); - HeapFree (GetProcessHeap (), 0, infoPtr->tics); - infoPtr->tics = NULL; - infoPtr->uNumTics = 2; + HeapFree (GetProcessHeap (), 0, infoPtr->tics); + infoPtr->tics = NULL; + infoPtr->uNumTics = 0; } if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -207,9 +432,8 @@ { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - if (wParam) - /* buddy is left or above */ - return (LRESULT)infoPtr->hwndBuddyLA; + if (wParam) /* buddy is left or above */ + return (LRESULT)infoPtr->hwndBuddyLA; /* buddy is right or below */ return (LRESULT) infoPtr->hwndBuddyRB; @@ -223,7 +447,7 @@ LPRECT32 lprc = (LPRECT32)lParam; if (lprc == NULL) - return 0; + return 0; lprc->left = infoPtr->rcChannel.left; lprc->right = infoPtr->rcChannel.right; @@ -249,9 +473,9 @@ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); if (wndPtr->dwStyle & TBS_NOTICKS) - return 0; + return 0; - return infoPtr->uNumTics; + return infoPtr->uNumTics+2; } @@ -273,7 +497,6 @@ } -// << TRACKBAR_GetPTics >> static LRESULT @@ -320,20 +543,78 @@ return infoPtr->uThumbLen; } +static LRESULT +TRACKBAR_GetPTics (WND *wndPtr) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + + return (LRESULT) infoPtr->tics; +} + +static LRESULT +TRACKBAR_GetThumbRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + LPRECT32 lprc = (LPRECT32)lParam; + + if (lprc == NULL) + return 0; + + lprc->left = infoPtr->rcThumb.left; + lprc->right = infoPtr->rcThumb.right; + lprc->bottom = infoPtr->rcThumb.bottom; + lprc->top = infoPtr->rcThumb.top; + + return 0; +} -// << TRACKBAR_GetThumbRect >> -// case TBM_GETTIC: -// case TBM_GETTICPOS: + +static LRESULT +TRACKBAR_GetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + INT32 iTic; + + iTic=(INT32) wParam; + if ((iTic<0) || (iTic>infoPtr->uNumTics)) + return -1; + + return (LRESULT) infoPtr->tics[iTic]; + +} + + +static LRESULT +TRACKBAR_GetTicPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + INT32 iTic, range, width, pos; + + + iTic=(INT32 ) wParam; + if ((iTic<0) || (iTic>infoPtr->uNumTics)) + return -1; + + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=infoPtr->rcChannel.right - infoPtr->rcChannel.left; + pos=infoPtr->rcChannel.left + width*(65536*infoPtr->tics[iTic]/range)/65536; + + + return (LRESULT) pos; +} + static LRESULT TRACKBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); if (wndPtr->dwStyle & TBS_TOOLTIPS) - return (LRESULT)infoPtr->hwndToolTip; + return (LRESULT)infoPtr->hwndToolTip; return 0; } @@ -355,11 +636,11 @@ FIXME (trackbar, "move buddy!\n"); } else { - /* buddy is right or below */ - hwndTemp = infoPtr->hwndBuddyRB; - infoPtr->hwndBuddyRB = (HWND32)lParam; + /* buddy is right or below */ + hwndTemp = infoPtr->hwndBuddyRB; + infoPtr->hwndBuddyRB = (HWND32)lParam; - FIXME (trackbar, "move buddy!\n"); + FIXME (trackbar, "move buddy!\n"); } TRACKBAR_AlignBuddies (wndPtr, infoPtr); @@ -404,11 +685,12 @@ if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax; + infoPtr->flags |=TB_THUMBCHANGED; if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -419,20 +701,26 @@ TRACKBAR_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - infoPtr->nRangeMin = (INT32)LOWORD(lParam); infoPtr->nRangeMax = (INT32)HIWORD(lParam); - if (infoPtr->nPos < infoPtr->nRangeMin) - infoPtr->nPos = infoPtr->nRangeMin; + if (infoPtr->nPos < infoPtr->nRangeMin) { + infoPtr->nPos = infoPtr->nRangeMin; + infoPtr->flags |=TB_THUMBCHANGED; + } - if (infoPtr->nPos > infoPtr->nRangeMax) - infoPtr->nPos = infoPtr->nRangeMax; + if (infoPtr->nPos > infoPtr->nRangeMax) { + infoPtr->nPos = infoPtr->nRangeMax; + infoPtr->flags |=TB_THUMBCHANGED; + } + + infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5; + TRACKBAR_RecalculateTics (infoPtr); if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -445,13 +733,18 @@ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); infoPtr->nRangeMax = (INT32)lParam; - if (infoPtr->nPos > infoPtr->nRangeMax) - infoPtr->nPos = infoPtr->nRangeMax; + if (infoPtr->nPos > infoPtr->nRangeMax) { + infoPtr->nPos = infoPtr->nRangeMax; + infoPtr->flags |=TB_THUMBCHANGED; + } + + infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5; + TRACKBAR_RecalculateTics (infoPtr); if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -464,39 +757,62 @@ TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); infoPtr->nRangeMin = (INT32)lParam; - if (infoPtr->nPos < infoPtr->nRangeMin) - infoPtr->nPos = infoPtr->nRangeMin; + if (infoPtr->nPos < infoPtr->nRangeMin) { + infoPtr->nPos = infoPtr->nRangeMin; + infoPtr->flags |=TB_THUMBCHANGED; + } + + infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5; + TRACKBAR_RecalculateTics (infoPtr); if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; } +static LRESULT +TRACKBAR_SetTicFreq (WND *wndPtr, WPARAM32 wParam) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + HDC32 hdc; + + if (wndPtr->dwStyle & TBS_AUTOTICKS) + infoPtr->uTicFreq=(UINT32) wParam; + + TRACKBAR_RecalculateTics (infoPtr); + + hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); + return 0; +} + static LRESULT TRACKBAR_SetSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - if (!wndPtr->dwStyle & TBS_ENABLESELRANGE) - return 0; - infoPtr->nSelMin = (INT32)LOWORD(lParam); infoPtr->nSelMax = (INT32)HIWORD(lParam); + infoPtr->flags |=TB_SELECTIONCHANGED; + + if (!wndPtr->dwStyle & TBS_ENABLESELRANGE) + return 0; if (infoPtr->nSelMin < infoPtr->nRangeMin) - infoPtr->nSelMin = infoPtr->nRangeMin; + infoPtr->nSelMin = infoPtr->nRangeMin; if (infoPtr->nSelMax > infoPtr->nRangeMax) - infoPtr->nSelMax = infoPtr->nRangeMax; + infoPtr->nSelMax = infoPtr->nRangeMax; if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -512,13 +828,15 @@ return 0; infoPtr->nSelMax = (INT32)lParam; + infoPtr->flags |=TB_SELECTIONCHANGED; + if (infoPtr->nSelMax > infoPtr->nRangeMax) - infoPtr->nSelMax = infoPtr->nRangeMax; + infoPtr->nSelMax = infoPtr->nRangeMax; if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -534,13 +852,14 @@ return 0; infoPtr->nSelMin = (INT32)lParam; + infoPtr->flags |=TB_SELECTIONCHANGED; if (infoPtr->nSelMin < infoPtr->nRangeMin) - infoPtr->nSelMin = infoPtr->nRangeMin; + infoPtr->nSelMin = infoPtr->nRangeMin; if (wParam) { - HDC32 hdc = GetDC32 (wndPtr->hwndSelf); - TRACKBAR_Refresh (wndPtr, hdc); - ReleaseDC32 (wndPtr->hwndSelf, hdc); + HDC32 hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); } return 0; @@ -551,10 +870,16 @@ TRACKBAR_SetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + HDC32 hdc; if (wndPtr->dwStyle & TBS_FIXEDLENGTH) - infoPtr->uThumbLen = (UINT32)wParam; + infoPtr->uThumbLen = (UINT32)wParam; + hdc = GetDC32 (wndPtr->hwndSelf); + infoPtr->flags |=TB_THUMBCHANGED; + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); + return 0; } @@ -564,19 +889,24 @@ { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); INT32 nPos = (INT32)lParam; + HDC32 hdc; - if (nPos < infoPtr->nRangeMin) - return FALSE; - if (nPos > infoPtr->nRangeMax) - return FALSE; + if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax)) + return FALSE; - FIXME (trackbar, "%d - empty stub!\n", nPos); + infoPtr->uNumTics++; + infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics, + (infoPtr->uNumTics)*sizeof (DWORD)); + infoPtr->tics[infoPtr->uNumTics-1]=nPos; + + hdc = GetDC32 (wndPtr->hwndSelf); + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); return TRUE; } -// case TBM_SETTICFREQ: static LRESULT @@ -586,7 +916,7 @@ INT32 fTemp = infoPtr->fLocation; infoPtr->fLocation = (INT32)wParam; - + return fTemp; } @@ -605,6 +935,19 @@ // case TBM_SETUNICODEFORMAT: +static LRESULT +TRACKBAR_InitializeThumb (WND *wndPtr) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + + infoPtr->uThumbLen = 23; /* initial thumb length */ + + TRACKBAR_Calc (wndPtr,infoPtr); + TRACKBAR_CalcThumb (wndPtr, infoPtr); + infoPtr->flags &= ~TB_SELECTIONCHANGED; + + return 0; +} static LRESULT @@ -617,18 +960,21 @@ wndPtr->wExtra[0] = (DWORD)infoPtr; - /* default values */ - infoPtr->nRangeMin = 0; + infoPtr->nRangeMin = 0; /* default values */ infoPtr->nRangeMax = 100; infoPtr->nLineSize = 1; infoPtr->nPageSize = 20; infoPtr->nSelMin = 0; infoPtr->nSelMax = 0; infoPtr->nPos = 0; - infoPtr->uThumbLen = 23; /* initial thumb length */ - infoPtr->uNumTics = 2; /* default start and end tic */ + infoPtr->uNumTics = 0; /* start and end tic are not included in count*/ + infoPtr->uTicFreq = 1; + infoPtr->tics = NULL; + infoPtr->clrBk = GetSysColor32 (COLOR_BACKGROUND); + TRACKBAR_InitializeThumb (wndPtr); + return 0; } @@ -667,12 +1013,64 @@ TRACKBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - + int prevPlace,range,width,clickPlace,prevPos; + SetFocus32 (wndPtr->hwndSelf); + clickPlace=(INT32)LOWORD(lParam); + range=infoPtr->nRangeMax - infoPtr->nRangeMin; + width=infoPtr->rcChannel.right - infoPtr->rcChannel.left; + prevPlace = infoPtr->rcChannel.left + + width*(65536*infoPtr->nPos/range)/65536; + printf ("%d->%d\n",prevPlace,clickPlace); + + prevPos = infoPtr->nPos; + if (clickPlace > prevPlace) { /* similar to VK_NEXT */ + infoPtr->nPos += infoPtr->nPageSize; + if (infoPtr->nPos > infoPtr->nRangeMax) + infoPtr->nPos = infoPtr->nRangeMax; + TRACKBAR_SendNotify (wndPtr, TB_PAGEUP); + } else { + infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */ + if (infoPtr->nPos < infoPtr->nRangeMin) + infoPtr->nPos = infoPtr->nRangeMin; + TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN); + } + + printf ("%d->%d\n",prevPos,infoPtr->nPos); + if (prevPos!=infoPtr->nPos) { + HDC32 hdc; + + hdc=GetDC32 (wndPtr->hwndSelf); + infoPtr->flags |=TB_THUMBCHANGED; + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); + } + + return 0; } +static LRESULT +TRACKBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + + FIXME (trackbar,"stub\n"); + + TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK); + + return 0; +} + +static LRESULT +TRACKBAR_CaptureChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + FIXME (trackbar,"stub\n"); + + TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK); + return 0; +} static LRESULT TRACKBAR_Paint (WND *wndPtr, WPARAM32 wParam) @@ -708,11 +1106,8 @@ TRACKBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); - RECT32 rcClient; - GetClientRect32 (wndPtr->hwndSelf, &rcClient); - - TRACKBAR_Calc (wndPtr, infoPtr, &rcClient); + TRACKBAR_Calc (wndPtr, infoPtr); TRACKBAR_AlignBuddies (wndPtr, infoPtr); return 0; @@ -720,9 +1115,111 @@ // << TRACKBAR_Timer >> -// << TRACKBAR_WinIniChange >> +static BOOL32 +TRACKBAR_SendNotify (WND *wndPtr, UINT32 code) + +{ + TRACE (trackbar, "%x\n",code); + if (wndPtr->dwStyle & TBS_VERT) + return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), + WM_VSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf); + + return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), + WM_HSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf); +} + +static LRESULT +TRACKBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + + + return TRUE; +} + + +static LRESULT +TRACKBAR_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr); + INT32 pos; + + TRACE (trackbar, "%x\n",wParam); + + pos=infoPtr->nPos; + switch (wParam) { + case VK_LEFT: + case VK_UP: + if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE; + infoPtr->nPos -= infoPtr->nLineSize; + if (infoPtr->nPos < infoPtr->nRangeMin) + infoPtr->nPos = infoPtr->nRangeMin; + TRACKBAR_SendNotify (wndPtr, TB_LINEUP); + break; + case VK_RIGHT: + case VK_DOWN: + if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE; + infoPtr->nPos += infoPtr->nLineSize; + if (infoPtr->nPos > infoPtr->nRangeMax) + infoPtr->nPos = infoPtr->nRangeMax; + TRACKBAR_SendNotify (wndPtr, TB_LINEDOWN); + break; + case VK_NEXT: + if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE; + infoPtr->nPos += infoPtr->nPageSize; + if (infoPtr->nPos > infoPtr->nRangeMax) + infoPtr->nPos = infoPtr->nRangeMax; + TRACKBAR_SendNotify (wndPtr, TB_PAGEUP); + break; + case VK_PRIOR: + if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE; + infoPtr->nPos -= infoPtr->nPageSize; + if (infoPtr->nPos < infoPtr->nRangeMin) + infoPtr->nPos = infoPtr->nRangeMin; + TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN); + break; + case VK_HOME: + if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE; + infoPtr->nPos = infoPtr->nRangeMin; + TRACKBAR_SendNotify (wndPtr, TB_TOP); + break; + case VK_END: + if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE; + infoPtr->nPos = infoPtr->nRangeMax; + TRACKBAR_SendNotify (wndPtr, TB_BOTTOM); + break; + } + + if (pos!=infoPtr->nPos) { + HDC32 hdc; + + hdc=GetDC32 (wndPtr->hwndSelf); + infoPtr->flags |=TB_THUMBCHANGED; + TRACKBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); + } + + return TRUE; +} + +static LRESULT +TRACKBAR_KeyUp (WND *wndPtr, WPARAM32 wParam) +{ + switch (wParam) { + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + case VK_NEXT: + case VK_PRIOR: + case VK_HOME: + case VK_END: TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK); + } + return TRUE; +} + LRESULT WINAPI TRACKBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) { @@ -754,7 +1251,8 @@ case TBM_GETPOS: return TRACKBAR_GetPos (wndPtr, wParam, lParam); -// case TBM_GETPTICS: + case TBM_GETPTICS: + return TRACKBAR_GetPTics (wndPtr); case TBM_GETRANGEMAX: return TRACKBAR_GetRangeMax (wndPtr, wParam, lParam); @@ -771,10 +1269,15 @@ case TBM_GETTHUMBLENGTH: return TRACKBAR_GetThumbLength (wndPtr, wParam, lParam); -// case TBM_GETTHUMBRECT: -// case TBM_GETTIC: -// case TBM_GETTICPOS: + case TBM_GETTHUMBRECT: + return TRACKBAR_GetThumbRect (wndPtr, wParam, lParam); + case TBM_GETTIC: + return TRACKBAR_GetTic (wndPtr, wParam, lParam); + + case TBM_GETTICPOS: + return TRACKBAR_GetTicPos (wndPtr, wParam, lParam); + case TBM_GETTOOLTIPS: return TRACKBAR_GetToolTips (wndPtr, wParam, lParam); @@ -816,7 +1319,9 @@ case TBM_SETTIC: return TRACKBAR_SetTic (wndPtr, wParam, lParam); -// case TBM_SETTICFREQ: + case TBM_SETTICFREQ: + return TRACKBAR_SetTicFreq (wndPtr, wParam); + case TBM_SETTIPSIDE: return TRACKBAR_SetTipSide (wndPtr, wParam, lParam); @@ -827,7 +1332,8 @@ // case TBM_SETUNICODEFORMAT: -// case WM_CAPTURECHANGED: + case WM_CAPTURECHANGED: + return TRACKBAR_CaptureChanged (wndPtr, wParam, lParam); case WM_CREATE: return TRACKBAR_Create (wndPtr, wParam, lParam); @@ -843,9 +1349,11 @@ case WM_GETDLGCODE: return DLGC_WANTARROWS; -// case WM_KEYDOWN: - -// case WM_KEYUP: + case WM_KEYDOWN: + return TRACKBAR_KeyDown (wndPtr, wParam, lParam); + + case WM_KEYUP: + return TRACKBAR_KeyUp (wndPtr, wParam); case WM_KILLFOCUS: return TRACKBAR_KillFocus (wndPtr, wParam, lParam); @@ -853,10 +1361,11 @@ case WM_LBUTTONDOWN: return TRACKBAR_LButtonDown (wndPtr, wParam, lParam); -// case WM_LBUTTONUP: + case WM_LBUTTONUP: + return TRACKBAR_LButtonUp (wndPtr, wParam, lParam); -// case WM_MOUSEMOVE: -// return TRACKBAR_MouseMove (wndPtr, wParam, lParam); + case WM_MOUSEMOVE: + return TRACKBAR_MouseMove (wndPtr, wParam, lParam); case WM_PAINT: return TRACKBAR_Paint (wndPtr, wParam); @@ -869,7 +1378,8 @@ // case WM_TIMER: -// case WM_WININICHANGE: + case WM_WININICHANGE: + return TRACKBAR_InitializeThumb (wndPtr); default: if (uMsg >= WM_USER)
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index a4eac47..9b5fcf5 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c
@@ -1,16 +1,28 @@ -/* - * Treeview control +/* Treeview control * - * Copyright 1998 Eric Kohl + * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de> + * Copyright 1998 Alex Priem <alexp@sci.kun.nl> * - * NOTES - * This is just a dummy control. An author is needed! Any volunteers? - * I will only improve this control once in a while. - * Eric <ekohl@abo.rhein-zeitung.de> * * TODO: - * - All messages. - * - All notifications. + * - Nearly all notifications. + * + * list-handling stuff: sort, sorted insertitem. + * + * refreshtreeview: + -small array containing info about positions. + -better implementation of DrawItem (connecting lines). + -implement partial drawing? + * Expand: -ctlmacro expands twice ->toggle. + * -drag&drop. + * -scrollbars. + * -Unicode messages + * -TVITEMEX + * + * FIXMEs: + -GetNextItem: add flag for traversing visible items + -DblClick: ctlmacro.exe's NM_DBLCLK seems to go wrong (returns FALSE). + */ #include "windows.h" @@ -19,26 +31,225 @@ #include "heap.h" #include "win.h" #include "debug.h" +#include <asm/bitops.h> /* FIXME: linux specific */ + +static int TREEVIEW_Timer; + #define TREEVIEW_GetInfoPtr(wndPtr) ((TREEVIEW_INFO *)wndPtr->wExtra[0]) +#include <asm/bitops.h> /* FIXME: linux specific */ + +static int TREEVIEW_Timer; + + + #define TREEVIEW_GetInfoPtr(wndPtr) ((TREEVIEW_INFO *)wndPtr->wExtra[0]) + + + + +static BOOL32 +TREEVIEW_SendSimpleNotify (WND *wndPtr, UINT32 code); +static BOOL32 +TREEVIEW_SendTreeviewNotify (WND *wndPtr, UINT32 code, UINT32 action, + INT32 oldItem, INT32 newItem, POINT32 pt); +static LRESULT +TREEVIEW_SelectItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam); +static void +TREEVIEW_Refresh (WND *wndPtr, HDC32 hdc); + + + + + +/* helper functions. Work with the assumption that validity of operands + is checked beforehand */ + + +static TREEVIEW_ITEM * +TREEVIEW_ValidItem (TREEVIEW_INFO *infoPtr,int handle) +{ + + if ((!handle) || (handle>infoPtr->uMaxHandle)) return NULL; + if (test_bit (handle, infoPtr->freeList)) return NULL; + + return & infoPtr->items[handle]; +} + + + +static TREEVIEW_ITEM *TREEVIEW_GetPrevListItem (TREEVIEW_INFO *infoPtr, + TREEVIEW_ITEM *tvItem) + +{ + TREEVIEW_ITEM *wineItem; + + if (tvItem->upsibling) + return (& infoPtr->items[tvItem->upsibling]); + + wineItem=tvItem; + while (wineItem->parent) { + wineItem=& infoPtr->items[wineItem->parent]; + if (wineItem->upsibling) + return (& infoPtr->items[wineItem->upsibling]); + } + + return NULL; +} + +static TREEVIEW_ITEM *TREEVIEW_GetNextListItem (TREEVIEW_INFO *infoPtr, + TREEVIEW_ITEM *tvItem) + +{ + TREEVIEW_ITEM *wineItem; + + if (tvItem->sibling) + return (& infoPtr->items[tvItem->sibling]); + + wineItem=tvItem; + while (wineItem->parent) { + wineItem=& infoPtr->items [wineItem->parent]; + if (wineItem->sibling) + return (& infoPtr->items [wineItem->sibling]); + } + + return NULL; +} + +static TREEVIEW_ITEM *TREEVIEW_GetLastListItem (TREEVIEW_INFO *infoPtr) + +{ + TREEVIEW_ITEM *wineItem; + + wineItem=NULL; + if (infoPtr->TopRootItem) + wineItem=& infoPtr->items [infoPtr->TopRootItem]; + while (wineItem->sibling) + wineItem=& infoPtr->items [wineItem->sibling]; + + return wineItem; +} + + + + +static void +TREEVIEW_RemoveItem (TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem) + +{ + TREEVIEW_ITEM *parentItem, *upsiblingItem, *siblingItem; + INT32 iItem; + + iItem=wineItem->hItem; + set_bit ( iItem & 31, &infoPtr->freeList[iItem >>5]); + infoPtr->uNumItems--; + parentItem=NULL; + if (wineItem->pszText!=LPSTR_TEXTCALLBACK32A) + HeapFree (GetProcessHeap (), 0, wineItem->pszText); + + if (wineItem->parent) { + parentItem=& infoPtr->items[ wineItem->parent]; + if (parentItem->cChildren==1) { + parentItem->cChildren=0; + parentItem->firstChild=0; + return; + } else { + parentItem->cChildren--; + if (parentItem->firstChild==iItem) + parentItem->firstChild=wineItem->sibling; + } + } + + if (iItem==infoPtr->TopRootItem) + infoPtr->TopRootItem=wineItem->sibling; + if (wineItem->upsibling) { + upsiblingItem=& infoPtr->items [wineItem->upsibling]; + upsiblingItem->sibling=wineItem->sibling; + } + if (wineItem->sibling) { + siblingItem=& infoPtr->items [wineItem->sibling]; + siblingItem->upsibling=wineItem->upsibling; + } +} + + + +static void TREEVIEW_RemoveAllChildren (TREEVIEW_INFO *infoPtr, + TREEVIEW_ITEM *parentItem) + +{ + TREEVIEW_ITEM *killItem; + INT32 kill; + + kill=parentItem->firstChild; + while (kill) { + set_bit ( kill & 31, &infoPtr->freeList[kill >>5]); + killItem=& infoPtr->items[kill]; + if (killItem->pszText!=LPSTR_TEXTCALLBACK32A) + HeapFree (GetProcessHeap (), 0, killItem->pszText); + kill=killItem->sibling; + } + infoPtr->uNumItems -= parentItem->cChildren; + parentItem->firstChild = 0; + parentItem->cChildren = 0; +} + + + +static void TREEVIEW_RemoveTree (TREEVIEW_INFO *infoPtr) + + +{ + TREEVIEW_ITEM *killItem; + int i; + + /* bummer: if we didn't delete anything, test_bit is overhead */ + + for (i=1; i<=infoPtr->uMaxHandle; i++) + if (!test_bit (i, infoPtr->freeList)) { + killItem=& infoPtr->items [i]; + if (killItem->pszText!=LPSTR_TEXTCALLBACK32A) + HeapFree (GetProcessHeap (), 0, killItem->pszText); + } + + if (infoPtr->uNumPtrsAlloced) { + HeapFree (GetProcessHeap (), 0, infoPtr->items); + HeapFree (GetProcessHeap (), 0, infoPtr->freeList); + infoPtr->uNumItems=0; + infoPtr->uNumPtrsAlloced=0; + infoPtr->uMaxHandle=0; + } + + /* this function doesn't remove infoPtr itself */ +} + + + + + + + + + + static LRESULT TREEVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { - TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); - switch ((INT32)wParam) { - case TVSIL_NORMAL: - return (LRESULT)infoPtr->himlNormal; + TRACE (treeview,"\n"); - case TVSIL_STATE: - return (LRESULT)infoPtr->himlState; - } + if (infoPtr==NULL) return 0; - return (LRESULT)NULL; + if ((INT32)wParam == TVSIL_NORMAL) + return (LRESULT) infoPtr->himlNormal; + if ((INT32)wParam == TVSIL_STATE) + return (LRESULT) infoPtr->himlState; + + return 0; } @@ -68,51 +279,862 @@ static LRESULT -TREEVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +TREEVIEW_SetItemHeight (WND *wndPtr, WPARAM32 wParam) { - TREEVIEW_INFO *infoPtr; + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + INT32 prevHeight=infoPtr->uItemHeight; + HDC32 hdc; + TEXTMETRIC32A tm; - /* allocate memory for info structure */ - infoPtr = (TREEVIEW_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(TREEVIEW_INFO)); - wndPtr->wExtra[0] = (DWORD)infoPtr; - if (infoPtr == NULL) { - ERR (treeview, "could not allocate info memory!\n"); - return 0; + if (wParam==-1) { + hdc=GetDC32 (wndPtr->hwndSelf); + infoPtr->uItemHeight=-1; + GetTextMetrics32A (hdc, &tm); + infoPtr->uRealItemHeight= tm.tmHeight + tm.tmExternalLeading; + ReleaseDC32 (wndPtr->hwndSelf, hdc); + return prevHeight; + } + + /* FIXME: check wParam > imagelist height */ + + if (!(wndPtr->dwStyle & TVS_NONEVENHEIGHT)) + infoPtr->uItemHeight = (INT32) wParam & 0xfffffffe; + return prevHeight; +} + +static LRESULT +TREEVIEW_GetItemHeight (WND *wndPtr) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + return infoPtr->uItemHeight; +} + +static LRESULT +TREEVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + COLORREF prevColor=infoPtr->clrText; + + infoPtr->clrText=(COLORREF) lParam; + return (LRESULT) prevColor; +} + +static LRESULT +TREEVIEW_GetTextColor (WND *wndPtr) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + return (LRESULT) infoPtr->clrText; +} + + +static INT32 +TREEVIEW_DrawItem (WND *wndPtr, HDC32 hdc, TREEVIEW_ITEM *wineItem, + TREEVIEW_ITEM *upperItem, int indent) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + INT32 oldBkMode,center,xpos; + COLORREF oldBkColor; + UINT32 uTextJustify = DT_LEFT; + HPEN32 hOldPen, hnewPen,hRootPen; + RECT32 r,upper; + + hnewPen = CreatePen32(PS_DOT, 0, GetSysColor32(COLOR_WINDOWTEXT) ); + hOldPen = SelectObject32( hdc, hnewPen ); + + r=wineItem->rect; + if (upperItem) + upper=upperItem->rect; + else { + upper.top=0; + upper.left=8; + } + center=(r.top+r.bottom)/2; + xpos=r.left+8; + + if (wndPtr->dwStyle & TVS_HASLINES) { + POINT32 points[3]; + if ((wndPtr->dwStyle & TVS_LINESATROOT) && (indent==0)) { + points[0].y=points[1].y=center; + points[2].y=upper.top; + points[1].x=points[2].x=upper.left; + points[0].x=upper.left+12; + points[2].y+=5; + + Polyline32 (hdc,points,3); + } + else { + points[0].y=points[1].y=center; + points[2].y=upper.top; + points[1].x=points[2].x=upper.left+13; + points[0].x=upper.left+25; + points[2].y+=5; + Polyline32 (hdc,points,3); + } + } + + DeleteObject32(hnewPen); + SelectObject32(hdc, hOldPen); + + if ((wndPtr->dwStyle & TVS_HASBUTTONS) && (wineItem->cChildren)) { +/* + hRootPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOW) ); + SelectObject32( hdc, hRootPen ); +*/ + + Rectangle32 (hdc, xpos-4, center-4, xpos+5, center+5); + MoveToEx32 (hdc, xpos-2, center, NULL); + LineTo32 (hdc, xpos+3, center); + if (!(wineItem->state & TVIS_EXPANDED)) { + MoveToEx32 (hdc, xpos, center-2, NULL); + LineTo32 (hdc, xpos, center+3); + } + /* DeleteObject32(hRootPen); */ + } + + + xpos+=13; + + if (wineItem->mask & TVIF_IMAGE) { + if (wineItem->iImage!=I_IMAGECALLBACK) { + if (infoPtr->himlNormal) { + ImageList_Draw (infoPtr->himlNormal,wineItem->iImage, hdc, + xpos-2, r.top+1, ILD_NORMAL); + xpos+=15; + } + } + } + + r.left=xpos; + if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText)) { + if (wineItem->state & TVIS_SELECTED) { + oldBkMode = SetBkMode32(hdc, OPAQUE); + oldBkColor= SetBkColor32 (hdc, GetSysColor32( COLOR_HIGHLIGHT)); + SetTextColor32 (hdc, GetSysColor32(COLOR_HIGHLIGHTTEXT)); + } + else { + oldBkMode = SetBkMode32(hdc, TRANSPARENT); + } + r.left += 3; + r.right -= 3; + if (infoPtr->clrText==-1) + SetTextColor32 (hdc, COLOR_BTNTEXT); + else + SetTextColor32 (hdc, infoPtr->clrText); /* FIXME: retval */ + DrawText32A(hdc, wineItem->pszText, lstrlen32A(wineItem->pszText), + &r, uTextJustify|DT_VCENTER|DT_SINGLELINE); + if (oldBkMode != TRANSPARENT) + SetBkMode32(hdc, oldBkMode); + if (wineItem->state & TVIS_SELECTED) + SetBkColor32 (hdc, oldBkColor); + } + + return wineItem->rect.right; +} + + + + + + + +static LRESULT +TREEVIEW_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + INT32 iItem; + LPRECT32 lpRect; + + TRACE (treeview,"\n"); + if (infoPtr==NULL) return FALSE; + + iItem = (INT32)lParam; + wineItem = TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return FALSE; + + wineItem=& infoPtr->items[ iItem ]; + if (!wineItem->visible) return FALSE; + + lpRect = (LPRECT32)lParam; + if (lpRect == NULL) return FALSE; + + if ((INT32) wParam) { + lpRect->left = wineItem->text.left; + lpRect->right = wineItem->text.right; + lpRect->bottom = wineItem->text.bottom; + lpRect->top = wineItem->text.top; + } else { + lpRect->left = wineItem->rect.left; + lpRect->right = wineItem->rect.right; + lpRect->bottom = wineItem->rect.bottom; + lpRect->top = wineItem->rect.top; + } + + return TRUE; +} + + + +static LRESULT +TREEVIEW_GetVisibleCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + TRACE (treeview,"\n"); + + return (LRESULT) infoPtr->uVisibleHeight / infoPtr->uRealItemHeight; +} + + + +static LRESULT +TREEVIEW_SetItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + TV_ITEM *tvItem; + INT32 iItem,len; + + TRACE (treeview,"\n"); + tvItem=(LPTVITEM) lParam; + iItem=tvItem->hItem; + + wineItem = TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return FALSE; + + if (tvItem->mask & TVIF_CHILDREN) { + wineItem->cChildren=tvItem->cChildren; + } + + if (tvItem->mask & TVIF_IMAGE) { + wineItem->iImage=tvItem->iImage; + } + + if (tvItem->mask & TVIF_INTEGRAL) { +/* wineItem->iIntegral=tvItem->iIntegral; */ + } + + if (tvItem->mask & TVIF_PARAM) { + wineItem->lParam=tvItem->lParam; + } + + if (tvItem->mask & TVIF_SELECTEDIMAGE) { + wineItem->iSelectedImage=tvItem->iSelectedImage; + } + + if (tvItem->mask & TVIF_STATE) { + wineItem->state=tvItem->state & tvItem->stateMask; + } + + if (tvItem->mask & TVIF_TEXT) { + len=tvItem->cchTextMax; + if (len>wineItem->cchTextMax) { + HeapFree (GetProcessHeap (), 0, wineItem->pszText); + wineItem->pszText= HeapAlloc (GetProcessHeap (), + HEAP_ZERO_MEMORY, len+1); + } + lstrcpyn32A (wineItem->pszText, tvItem->pszText,len); + } + + return TRUE; +} + + + + + +static void +TREEVIEW_Refresh (WND *wndPtr, HDC32 hdc) + +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + HFONT32 hFont, hOldFont; + RECT32 rect; + HBRUSH32 hbrBk; + INT32 iItem, indent, x, y, height; + INT32 viewtop,viewbottom,viewleft,viewright; + TREEVIEW_ITEM *wineItem, *prevItem; + + TRACE (treeview,"\n"); + + if (TREEVIEW_Timer & TV_REFRESH_TIMER_SET) { + KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER); + TREEVIEW_Timer &= ~TV_REFRESH_TIMER_SET; } - if ((TREEVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) { - ERR (treeview, "pointer assignment error!\n"); - return 0; - } + + GetClientRect32 (wndPtr->hwndSelf, &rect); + if ((rect.left-rect.right ==0) || (rect.top-rect.bottom==0)) return; + viewtop=infoPtr->cy; + viewbottom=infoPtr->cy + rect.bottom-rect.top; + viewleft=infoPtr->cx; + viewright=infoPtr->cx + rect.right-rect.left; - /* set default settings */ - infoPtr->clrBk = GetSysColor32 (COLOR_WINDOW); - infoPtr->clrText = GetSysColor32 (COLOR_BTNTEXT); - infoPtr->himlNormal = NULL; - infoPtr->himlState = NULL; + infoPtr->uVisibleHeight=viewbottom - viewtop; + + hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (DEFAULT_GUI_FONT); + hOldFont = SelectObject32 (hdc, hFont); + + /* draw background */ + hbrBk = GetSysColorBrush32(COLOR_WINDOW); + FillRect32(hdc, &rect, hbrBk); - return 0; + iItem=infoPtr->TopRootItem; + infoPtr->firstVisible=0; + wineItem=NULL; + indent=0; + x=y=0; + TRACE (treeview, "[%d %d %d %d]\n",viewtop,viewbottom,viewleft,viewright); + + while (iItem) { + prevItem=wineItem; + wineItem= & infoPtr->items[iItem]; + + TRACE (treeview, "%d %d [%d %d %d %d] (%s)\n",y,x, + wineItem->rect.top, wineItem->rect.bottom, + wineItem->rect.left, wineItem->rect.right, + wineItem->pszText); + + height=infoPtr->uRealItemHeight * wineItem->iIntegral; + if ((y >= viewtop) && (y <= viewbottom) && + (x >= viewleft ) && (x <= viewright)) { + wineItem->rect.top = y - infoPtr->cy + rect.top; + wineItem->rect.bottom = wineItem->rect.top + height ; + wineItem->rect.left = x - infoPtr->cx + rect.left; + wineItem->rect.right = rect.right; + if (!infoPtr->firstVisible) + infoPtr->firstVisible=wineItem->hItem; + TREEVIEW_DrawItem (wndPtr, hdc, wineItem, prevItem, indent); + } + else { + wineItem->rect.top = wineItem->rect.bottom = -1; + wineItem->rect.left = wineItem->rect.right = -1; + } + + /* look up next item */ + + if ((wineItem->firstChild) && (wineItem->state & TVIS_EXPANDED)) { + iItem=wineItem->firstChild; + indent++; + x+=infoPtr->uIndent; + } + else { + iItem=wineItem->sibling; + while ((!iItem) && (indent>0)) { + indent--; + x-=infoPtr->uIndent; + prevItem=wineItem; + wineItem=&infoPtr->items[wineItem->parent]; + iItem=wineItem->sibling; + } + } + y +=height; + } /* while */ + + infoPtr->uTotalHeight=y; + if (y >= (viewbottom-viewtop)) { + if (!(infoPtr->uInternalStatus & TV_VSCROLL)) + ShowScrollBar32 (wndPtr->hwndSelf, SB_VERT, TRUE); + infoPtr->uInternalStatus |=TV_VSCROLL; + SetScrollRange32 (wndPtr->hwndSelf, SB_VERT, 0, + y - infoPtr->uVisibleHeight, FALSE); + SetScrollPos32 (wndPtr->hwndSelf, SB_VERT, infoPtr->cy, TRUE); + } + else { + if (infoPtr->uInternalStatus & TV_VSCROLL) + ShowScrollBar32 (wndPtr->hwndSelf, SB_VERT, FALSE); + infoPtr->uInternalStatus &= ~TV_VSCROLL; + } + + + SelectObject32 (hdc, hOldFont); +} + + +static LRESULT +TREEVIEW_HandleTimer ( WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + HDC32 hdc; + + if (!infoPtr) return FALSE; + + TRACE (treeview, "timer\n"); + + switch (wParam) { + case TV_REFRESH_TIMER: + KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER); + TREEVIEW_Timer &= ~TV_REFRESH_TIMER_SET; + hdc=GetDC32 (wndPtr->hwndSelf); + TREEVIEW_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); + return 0; + case TV_EDIT_TIMER: + KillTimer32 (wndPtr->hwndSelf, TV_EDIT_TIMER); + TREEVIEW_Timer &= ~TV_EDIT_TIMER_SET; + return 0; + } + + return 1; +} + + +static void +TREEVIEW_QueueRefresh (WND *wndPtr) + +{ + + TRACE (treeview,"queued\n"); + if (TREEVIEW_Timer & TV_REFRESH_TIMER_SET) { + KillTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER); + } + + SetTimer32 (wndPtr->hwndSelf, TV_REFRESH_TIMER, TV_REFRESH_DELAY, 0); + TREEVIEW_Timer|=TV_REFRESH_TIMER_SET; +} + + + +static LRESULT +TREEVIEW_GetItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + LPTVITEM tvItem; + TREEVIEW_ITEM *wineItem; + INT32 iItem,len; + + TRACE (treeview,"\n"); + tvItem=(LPTVITEM) lParam; + iItem=tvItem->hItem; + + wineItem = TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return FALSE; + + + if (tvItem->mask & TVIF_CHILDREN) { + tvItem->cChildren=wineItem->cChildren; + } + + if (tvItem->mask & TVIF_HANDLE) { + tvItem->hItem=wineItem->hItem; + } + + if (tvItem->mask & TVIF_IMAGE) { + tvItem->iImage=wineItem->iImage; + } + + if (tvItem->mask & TVIF_INTEGRAL) { +/* tvItem->iIntegral=wineItem->iIntegral; */ + } + + if (tvItem->mask & TVIF_PARAM) { + tvItem->lParam=wineItem->lParam; + } + + if (tvItem->mask & TVIF_SELECTEDIMAGE) { + tvItem->iSelectedImage=wineItem->iSelectedImage; + } + + if (tvItem->mask & TVIF_STATE) { + tvItem->state=wineItem->state & tvItem->stateMask; + } + + if (tvItem->mask & TVIF_TEXT) { + len=wineItem->cchTextMax; + if (wineItem->cchTextMax>tvItem->cchTextMax) + len=tvItem->cchTextMax-1; + lstrcpyn32A (tvItem->pszText, tvItem->pszText,len); + } + + return TRUE; +} + + + +static LRESULT +TREEVIEW_GetNextItem32 (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + INT32 iItem, flag; + + + TRACE (treeview,"item:%lu, flags:%x\n", lParam, wParam); + if (!infoPtr) return FALSE; + + flag= (INT32) wParam; + switch (flag) { + case TVGN_ROOT: return (LRESULT) infoPtr->TopRootItem; + case TVGN_CARET: return (LRESULT) infoPtr->selectedItem; + case TVGN_FIRSTVISIBLE: return (LRESULT) infoPtr->firstVisible; + case TVGN_DROPHILITE: return (LRESULT) infoPtr->dropItem; + } + + iItem= (INT32) lParam; + wineItem = TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return FALSE; + + switch (flag) { + case TVGN_NEXT: return (LRESULT) wineItem->sibling; + case TVGN_PREVIOUS: return (LRESULT) wineItem->upsibling; + case TVGN_PARENT: return (LRESULT) wineItem->parent; + case TVGN_CHILD: return (LRESULT) wineItem->firstChild; + case TVGN_LASTVISIBLE: FIXME (treeview,"TVGN_LASTVISIBLE not implemented\n"); + return 0; + case TVGN_NEXTVISIBLE: wineItem=TREEVIEW_GetNextListItem + (infoPtr,wineItem); + if (wineItem) + return (LRESULT) wineItem->hItem; + else + return (LRESULT) 0; + case TVGN_PREVIOUSVISIBLE: wineItem=TREEVIEW_GetPrevListItem + (infoPtr, wineItem); + if (wineItem) + return (LRESULT) wineItem->hItem; + else + return (LRESULT) 0; + default: FIXME (treeview,"Unknown msg %x,item %x\n", flag,iItem); + } + + return 0; } static LRESULT -TREEVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +TREEVIEW_GetCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { - TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + return (LRESULT) infoPtr->uNumItems; +} - /* free tree view info data */ - HeapFree (GetProcessHeap (), 0, infoPtr); +/* the method used below isn't the most memory-friendly, but it avoids + a lot of memory reallocations */ + +/* BTW: we waste handle 0; 0 is not an allowed handle. Fix this by + decreasing infoptr->items with 1, and increasing it by 1 if + it is referenced in mm-handling stuff? */ + +static LRESULT +TREEVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TVINSERTSTRUCT *ptdi; + TV_ITEM *tvItem; + TREEVIEW_ITEM *wineItem, *parentItem, *prevsib, *sibItem; + INT32 iItem,listItems,i,len; + + TRACE (treeview,"\n"); + ptdi = (TVINSERTSTRUCT *) lParam; + + /* check if memory is available */ + + if (infoPtr->uNumPtrsAlloced==0) { + infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + TVITEM_ALLOC*sizeof (TREEVIEW_ITEM)); + infoPtr->freeList= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + (1+(TVITEM_ALLOC>>5)) *sizeof (INT32)); + infoPtr->uNumPtrsAlloced=TVITEM_ALLOC; + infoPtr->TopRootItem=1; + } + + if (infoPtr->uNumItems == (infoPtr->uNumPtrsAlloced-1) ) { + TREEVIEW_ITEM *oldItems = infoPtr->items; + INT32 *oldfreeList = infoPtr->freeList; + + infoPtr->uNumPtrsAlloced*=2; + infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + infoPtr->uNumPtrsAlloced*sizeof (TREEVIEW_ITEM)); + infoPtr->freeList= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + (1+(infoPtr->uNumPtrsAlloced>>5))*sizeof (INT32)); + + memcpy (&infoPtr->items[0], &oldItems[0], + infoPtr->uNumPtrsAlloced/2 * sizeof(TREEVIEW_ITEM)); + memcpy (&infoPtr->freeList[0], &oldfreeList[0], + infoPtr->uNumPtrsAlloced>>6 * sizeof(INT32)); + + HeapFree (GetProcessHeap (), 0, oldItems); + HeapFree (GetProcessHeap (), 0, oldfreeList); + } + + iItem=0; + infoPtr->uNumItems++; + + if (infoPtr->uMaxHandle==(infoPtr->uNumItems-1)) { + iItem=infoPtr->uNumItems; + infoPtr->uMaxHandle++; + } + else { /* check freelist */ + for (i=0; i<infoPtr->uNumPtrsAlloced>>5; i++) { + if (infoPtr->freeList[i]) { + iItem=ffs (infoPtr->freeList[i]); + clear_bit (iItem & 31, & infoPtr->freeList[i]); + break; + } + } + } + if (!iItem) ERR (treeview, "Argh -- can't find free item.\n"); + + tvItem= & ptdi->item; + wineItem=& infoPtr->items[iItem]; + + + + if ((ptdi->hParent==TVI_ROOT) || (ptdi->hParent==0)) { + parentItem=NULL; + wineItem->parent=0; + sibItem=&infoPtr->items [infoPtr->TopRootItem]; + listItems=infoPtr->uNumItems; + } + else { + parentItem= &infoPtr->items[ptdi->hParent]; + if (!parentItem->firstChild) + parentItem->firstChild=iItem; + wineItem->parent=ptdi->hParent; + sibItem=&infoPtr->items [parentItem->firstChild]; + parentItem->cChildren++; + listItems=parentItem->cChildren; + } + + wineItem->upsibling=0; /* needed in case we're the first item in a list */ + wineItem->sibling=0; + wineItem->firstChild=0; + + if (listItems>1) { + prevsib=NULL; + switch (ptdi->hInsertAfter) { + case TVI_FIRST: wineItem->sibling=infoPtr->TopRootItem; + infoPtr->TopRootItem=iItem; + break; + case TVI_LAST: + while (sibItem->sibling) { + prevsib=sibItem; + sibItem=&infoPtr->items [sibItem->sibling]; + } + sibItem->sibling=iItem; + if (prevsib!=NULL) + wineItem->upsibling=prevsib->hItem; + else + wineItem->sibling=0; /* terminate list */ + break; + case TVI_SORT: + FIXME (treeview, "Sorted insert not implemented yet\n"); + break; + default: + while ((sibItem->sibling) && (sibItem->sibling!=iItem)) { + prevsib=sibItem; + sibItem=&infoPtr->items [sibItem->sibling]; + } + if (sibItem->sibling) + WARN (treeview, "Buggy program tried to insert item after nonexisting handle."); + sibItem->upsibling=iItem; + wineItem->sibling=sibItem->hItem; + if (prevsib!=NULL) + wineItem->upsibling=prevsib->hItem; + break; + } + } + + +/* Fill in info structure */ + + wineItem->mask=tvItem->mask; + wineItem->hItem=iItem; + wineItem->iIntegral=1; + + if (tvItem->mask & TVIF_CHILDREN) + wineItem->cChildren=tvItem->cChildren; + + if (tvItem->mask & TVIF_IMAGE) + wineItem->iImage=tvItem->iImage; + +/* if (tvItem->mask & TVIF_INTEGRAL) + wineItem->iIntegral=tvItem->iIntegral; */ + + + if (tvItem->mask & TVIF_PARAM) + wineItem->lParam=tvItem->lParam; + + if (tvItem->mask & TVIF_SELECTEDIMAGE) + wineItem->iSelectedImage=tvItem->iSelectedImage; + + if (tvItem->mask & TVIF_STATE) { + wineItem->state=tvItem->state; + wineItem->stateMask=tvItem->stateMask; + } + + if (tvItem->mask & TVIF_TEXT) { + TRACE (treeview,"(%s)\n", tvItem->pszText); + if (tvItem->pszText!=LPSTR_TEXTCALLBACK32A) { + len = lstrlen32A (tvItem->pszText)+1; + wineItem->pszText= + HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); + lstrcpy32A (wineItem->pszText, tvItem->pszText); + wineItem->cchTextMax=len; + } + } + + TREEVIEW_QueueRefresh (wndPtr); + + return (LRESULT) iItem; +} + + + +static LRESULT +TREEVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + INT32 iItem; + POINT32 pt; + TREEVIEW_ITEM *wineItem; + + TRACE (treeview,"\n"); + if (!infoPtr) return FALSE; + + if ((INT32) lParam == TVI_ROOT) { + TREEVIEW_RemoveTree (infoPtr); + } else { + iItem= (INT32) lParam; + wineItem = TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return FALSE; + TREEVIEW_SendTreeviewNotify (wndPtr, TVN_DELETEITEM, 0, iItem, 0, pt); + TREEVIEW_RemoveItem (infoPtr, wineItem); + } + + TREEVIEW_QueueRefresh (wndPtr); + + return TRUE; +} + + +static LRESULT +TREEVIEW_GetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + return infoPtr->uIndent; +} + +static LRESULT +TREEVIEW_SetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + INT32 newIndent; + + newIndent=(INT32) wParam; + if (newIndent < MINIMUM_INDENT) newIndent=MINIMUM_INDENT; + infoPtr->uIndent=newIndent; + + return 0; +} + + + + + +static LRESULT +TREEVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr; + HDC32 hdc; + TEXTMETRIC32A tm; + + TRACE (treeview,"\n"); + /* allocate memory for info structure */ + infoPtr = (TREEVIEW_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + sizeof(TREEVIEW_INFO)); + + wndPtr->wExtra[0] = (DWORD)infoPtr; + + if (infoPtr == NULL) { + ERR (treeview, "could not allocate info memory!\n"); + return 0; + } + + if ((TREEVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) { + ERR (treeview, "pointer assignment error!\n"); + return 0; + } + + hdc=GetDC32 (wndPtr->hwndSelf); + + /* set default settings */ + infoPtr->uInternalStatus=0; + infoPtr->uNumItems=0; + infoPtr->clrBk = GetSysColor32 (COLOR_WINDOW); + infoPtr->clrText = GetSysColor32 (COLOR_BTNTEXT); + infoPtr->cy = 0; + infoPtr->cx = 0; + infoPtr->uIndent = 15; + infoPtr->himlNormal = NULL; + infoPtr->himlState = NULL; + infoPtr->uItemHeight = -1; + GetTextMetrics32A (hdc, &tm); + infoPtr->uRealItemHeight= tm.tmHeight + tm.tmExternalLeading; + + infoPtr->items = NULL; + infoPtr->selectedItem=0; + infoPtr->clrText=-1; /* use system color */ + infoPtr->dropItem=0; + +/* + infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf); + infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT); +*/ + + if (wndPtr->dwStyle & TBSTYLE_TOOLTIPS) { + /* Create tooltip control */ +// infoPtr->hwndToolTip = CreateWindowEx32A (....); + + /* Send TV_TOOLTIPSCREATED notification */ + + } + ReleaseDC32 (wndPtr->hwndSelf, hdc); return 0; } + +static LRESULT +TREEVIEW_Destroy (WND *wndPtr) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + TREEVIEW_RemoveTree (infoPtr); + + HeapFree (GetProcessHeap (), 0, infoPtr); + + return 0; +} + + +static LRESULT +TREEVIEW_Paint (WND *wndPtr, WPARAM32 wParam) +{ + HDC32 hdc; + PAINTSTRUCT32 ps; + + hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam; + TREEVIEW_QueueRefresh (wndPtr); + if(!wParam) + EndPaint32 (wndPtr->hwndSelf, &ps); + return 0; +} + + + static LRESULT TREEVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { @@ -120,6 +1142,7 @@ HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk); RECT32 rect; + TRACE (treeview,"\n"); GetClientRect32 (wndPtr->hwndSelf, &rect); FillRect32 ((HDC32)wParam, &rect, hBrush); DeleteObject32 (hBrush); @@ -128,161 +1151,653 @@ -LRESULT WINAPI -TREEVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) + + + + + + +static BOOL32 +TREEVIEW_SendSimpleNotify (WND *wndPtr, UINT32 code) { - WND *wndPtr = WIN_FindWndPtr(hwnd); + NMHDR nmhdr; - switch (uMsg) - { + TRACE (treeview, "%x\n",code); + nmhdr.hwndFrom = wndPtr->hwndSelf; + nmhdr.idFrom = wndPtr->wIDmenu; + nmhdr.code = code; - case TVM_INSERTITEM32A: - FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32A\n"); - return 0; + return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)nmhdr.idFrom, (LPARAM)&nmhdr); +} - case TVM_INSERTITEM32W: - FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32W\n"); - return 0; - case TVM_DELETEITEM: - FIXME (treeview, "Unimplemented msg TVM_DELETEITEM\n"); - return 0; - case TVM_EXPAND: - FIXME (treeview, "Unimplemented msg TVM_EXPAND\n"); - return 0; - case TVM_GETITEMRECT: - FIXME (treeview, "Unimplemented msg TVM_GETITEMRECT\n"); - return 0; +static BOOL32 +TREEVIEW_SendTreeviewNotify (WND *wndPtr, UINT32 code, UINT32 action, + INT32 oldItem, INT32 newItem, POINT32 pt) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + NMTREEVIEW nmhdr; + TREEVIEW_ITEM *wineItem; - case TVM_GETCOUNT: - FIXME (treeview, "Unimplemented msg TVM_GETCOUNT\n"); - return 0; + TRACE (treeview,"code:%x action:%x olditem:%x newitem:%x\n", + code,action,oldItem,newItem); + nmhdr.hdr.hwndFrom = wndPtr->hwndSelf; + nmhdr.hdr.idFrom = wndPtr->wIDmenu; + nmhdr.hdr.code = code; + nmhdr.action = action; + if (oldItem) { + wineItem=& infoPtr->items[oldItem]; + nmhdr.itemOld.mask = wineItem->mask; + nmhdr.itemOld.hItem = wineItem->hItem; + nmhdr.itemOld.state = wineItem->state; + nmhdr.itemOld.stateMask = wineItem->stateMask; + nmhdr.itemOld.iImage = wineItem->iImage; + nmhdr.itemOld.pszText = wineItem->pszText; + nmhdr.itemOld.cchTextMax = wineItem->cchTextMax; + nmhdr.itemOld.iImage = wineItem->iImage; + nmhdr.itemOld.iSelectedImage = wineItem->iSelectedImage; + nmhdr.itemOld.cChildren = wineItem->cChildren; + nmhdr.itemOld.lParam = wineItem->lParam; + } - case TVM_GETINDENT: - FIXME (treeview, "Unimplemented msg TVM_GETINDENT\n"); - return 0; + if (newItem) { + wineItem=& infoPtr->items[newItem]; + nmhdr.itemNew.mask = wineItem->mask; + nmhdr.itemNew.hItem = wineItem->hItem; + nmhdr.itemNew.state = wineItem->state; + nmhdr.itemNew.stateMask = wineItem->stateMask; + nmhdr.itemNew.iImage = wineItem->iImage; + nmhdr.itemNew.pszText = wineItem->pszText; + nmhdr.itemNew.cchTextMax = wineItem->cchTextMax; + nmhdr.itemNew.iImage = wineItem->iImage; + nmhdr.itemNew.iSelectedImage = wineItem->iSelectedImage; + nmhdr.itemNew.cChildren = wineItem->cChildren; + nmhdr.itemNew.lParam = wineItem->lParam; + } - case TVM_SETINDENT: - FIXME (treeview, "Unimplemented msg TVM_SETINDENT\n"); - return 0; + nmhdr.ptDrag.x = pt.x; + nmhdr.ptDrag.y = pt.y; - case TVM_GETIMAGELIST: - return TREEVIEW_GetImageList (wndPtr, wParam, lParam); + return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, + (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr); - case TVM_SETIMAGELIST: - return TREEVIEW_SetImageList (wndPtr, wParam, lParam); +} - case TVM_GETNEXTITEM: - FIXME (treeview, "Unimplemented msg TVM_GETNEXTITEM\n"); - return 0; - case TVM_SELECTITEM: - FIXME (treeview, "Unimplemented msg TVM_SELECTITEM \n"); - return 0; - case TVM_GETITEM32A: - FIXME (treeview, "Unimplemented msg TVM_GETITEM32A\n"); - return 0; - case TVM_GETITEM32W: - FIXME (treeview, "Unimplemented msg TVM_GETITEM32W\n"); - return 0; +static LRESULT +TREEVIEW_Expand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + UINT32 flag; + INT32 expandItem; + POINT32 pt; + + flag= (UINT32) wParam; + expandItem= (INT32) lParam; + TRACE (treeview,"flags:%x item:%x\n", expandItem, wParam); + wineItem = TREEVIEW_ValidItem (infoPtr, expandItem); + if (!wineItem) return 0; + if (!wineItem->cChildren) return 0; - case TVM_SETITEM32A: - FIXME (treeview, "Unimplemented msg TVM_SETITEM32A\n"); - return 0; + if (flag & TVE_TOGGLE) { /* FIXME: check exact behaviour here */ + flag &= ~TVE_TOGGLE; /* ie: bitwise ops or 'case' ops */ + if (wineItem->state & TVIS_EXPANDED) + flag |= TVE_COLLAPSE; + else + flag |= TVE_EXPAND; + } - case TVM_SETITEM32W: - FIXME (treeview, "Unimplemented msg TVM_SETITEM32W\n"); - return 0; + switch (flag) { + case TVE_COLLAPSERESET: + if (!wineItem->state & TVIS_EXPANDED) return 0; + wineItem->state &= ~(TVIS_EXPANDEDONCE | TVIS_EXPANDED); + TREEVIEW_RemoveAllChildren (infoPtr, wineItem); + break; - case TVM_EDITLABEL32A: - FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32A\n"); - return 0; + case TVE_COLLAPSE: + if (!wineItem->state & TVIS_EXPANDED) return 0; + wineItem->state &= ~TVIS_EXPANDED; + break; - case TVM_EDITLABEL32W: - FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32W\n"); - return 0; + case TVE_EXPAND: + if (wineItem->state & TVIS_EXPANDED) return 0; + if (!(wineItem->state & TVIS_EXPANDEDONCE)) { + if (TREEVIEW_SendTreeviewNotify (wndPtr, TVN_ITEMEXPANDING, + 0, 0, expandItem, pt)) + return FALSE; /* FIXME: OK? */ + wineItem->state |= TVIS_EXPANDED | TVIS_EXPANDEDONCE; + TREEVIEW_SendTreeviewNotify (wndPtr, TVN_ITEMEXPANDED, + 0, 0, expandItem, pt); + } + wineItem->state |= TVIS_EXPANDED; + break; + case TVE_EXPANDPARTIAL: + FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n"); + wineItem->state ^=TVIS_EXPANDED; + wineItem->state |=TVIS_EXPANDEDONCE; + break; + } + + TREEVIEW_QueueRefresh (wndPtr); - case TVM_GETEDITCONTROL: - FIXME (treeview, "Unimplemented msg TVM_GETEDITCONTROL\n"); - return 0; + return TRUE; +} - case TVM_GETVISIBLECOUNT: - FIXME (treeview, "Unimplemented msg TVM_GETVISIBLECOUNT\n"); - return 0; - case TVM_HITTEST: - FIXME (treeview, "Unimplemented msg TVM_HITTEST\n"); - return 0; - case TVM_CREATEDRAGIMAGE: - FIXME (treeview, "Unimplemented msg TVM_CREATEDRAGIMAGE\n"); - return 0; +static HTREEITEM +TREEVIEW_HitTest (WND *wndPtr, LPTVHITTESTINFO lpht) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + RECT32 rect; + UINT32 status,x,y; + - case TVM_SORTCHILDREN: - FIXME (treeview, "Unimplemented msg TVM_SORTCHILDREN\n"); - return 0; - case TVM_ENSUREVISIBLE: - FIXME (treeview, "Unimplemented msg TVM_ENSUREVISIBLE\n"); - return 0; + GetClientRect32 (wndPtr->hwndSelf, &rect); + TRACE (treeview,"(%d,%d)\n",lpht->pt.x, lpht->pt.y); - case TVM_SORTCHILDRENCB: - FIXME (treeview, "Unimplemented msg TVM_SORTCHILDRENCB\n"); - return 0; + status=0; + x=lpht->pt.x; + y=lpht->pt.y; + if (x < rect.left) status|=TVHT_TOLEFT; + if (x > rect.right) status|=TVHT_TORIGHT; + if (y < rect.top ) status|=TVHT_ABOVE; + if (y > rect.bottom) status|=TVHT_BELOW; + if (status) { + lpht->flags=status; + return 0; + } - case TVM_ENDEDITLABELNOW: - FIXME (treeview, "Unimplemented msg TVM_ENDEDITLABELNOW\n"); - return 0; + if (!infoPtr->firstVisible) WARN (treeview,"Can't fetch first visible item"); + wineItem=&infoPtr->items [infoPtr->firstVisible]; - case TVM_GETISEARCHSTRING32A: - FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32A\n"); - return 0; + while ((wineItem!=NULL) && (y > wineItem->rect.bottom)) + wineItem=TREEVIEW_GetNextListItem (infoPtr,wineItem); + + if (wineItem==NULL) { + lpht->flags=TVHT_NOWHERE; + return 0; + } - case TVM_GETISEARCHSTRING32W: - FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32W\n"); - return 0; + if (x>wineItem->rect.right) { + lpht->flags|=TVHT_ONITEMRIGHT; + return wineItem->hItem; + } + + + if (x<wineItem->rect.left+10) lpht->flags|=TVHT_ONITEMBUTTON; - case TVM_SETTOOLTIPS: - FIXME (treeview, "Unimplemented msg TVM_SETTOOLTIPS\n"); - return 0; + lpht->flags=TVHT_ONITEMLABEL; /* FIXME: implement other flags */ + - case TVM_GETTOOLTIPS: - FIXME (treeview, "Unimplemented msg TVM_GETTOOLTIPS\n"); - return 0; + lpht->hItem=wineItem->hItem; + return wineItem->hItem; +} - case WM_CREATE: - return TREEVIEW_Create (wndPtr, wParam, lParam); - case WM_DESTROY: - return TREEVIEW_Destroy (wndPtr, wParam, lParam); +static LRESULT +TREEVIEW_HitTest32 (WND *wndPtr, LPARAM lParam) +{ + + return (LRESULT) TREEVIEW_HitTest (wndPtr, (LPTVHITTESTINFO) lParam); +} -// case EM_ENABLE: - case WM_ERASEBKGND: - return TREEVIEW_EraseBackground (wndPtr, wParam, lParam); - case WM_GETDLGCODE: - return DLGC_WANTARROWS | DLGC_WANTCHARS; -// case WM_PAINT: -// return TREEVIEW_Paint (wndPtr, wParam); +LRESULT +TREEVIEW_LButtonDoubleClick (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *wineItem; + INT32 iItem; + TVHITTESTINFO ht; -// case WM_SETFONT: + TRACE (treeview,"\n"); + ht.pt.x = (INT32)LOWORD(lParam); + ht.pt.y = (INT32)HIWORD(lParam); + SetFocus32 (wndPtr->hwndSelf); -// case WM_TIMER: + iItem=TREEVIEW_HitTest (wndPtr, &ht); + TRACE (treeview,"item %d \n",iItem); + wineItem=TREEVIEW_ValidItem (infoPtr, iItem); + if (!wineItem) return 0; + + if (TREEVIEW_SendSimpleNotify (wndPtr, NM_DBLCLK)!=TRUE) { /* FIXME!*/ + wineItem->state &= ~TVIS_EXPANDEDONCE; + TREEVIEW_Expand (wndPtr, (WPARAM32) TVE_TOGGLE, (LPARAM) iItem); + } + return TRUE; +} -// case WM_VSCROLL: - default: - if (uMsg >= WM_USER) + +static LRESULT +TREEVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + INT32 iItem; + TVHITTESTINFO ht; + + TRACE (treeview,"\n"); + ht.pt.x = (INT32)LOWORD(lParam); + ht.pt.y = (INT32)HIWORD(lParam); + + SetFocus32 (wndPtr->hwndSelf); + iItem=TREEVIEW_HitTest (wndPtr, &ht); + TRACE (treeview,"item %d \n",iItem); + if (ht.flags & TVHT_ONITEMBUTTON) { + TREEVIEW_Expand (wndPtr, (WPARAM32) TVE_TOGGLE, (LPARAM) iItem); + } + + if (TREEVIEW_SelectItem (wndPtr, (WPARAM32) TVGN_CARET, (LPARAM) iItem)) + return 0; + + + return 0; +} + + +static LRESULT +TREEVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + + return 0; +} + + + + +/* FIXME: If the specified item is the child of a collapsed parent item, +expand parent's list of child items to reveal the specified item. +*/ + +static LRESULT +TREEVIEW_SelectItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *prevItem,*wineItem; + INT32 action,prevSelect, newSelect; + POINT32 dummy; + + TRACE (treeview,"item %lx, flag %x\n", lParam, wParam); + newSelect= (INT32) lParam; + wineItem = TREEVIEW_ValidItem (infoPtr, newSelect); + if (!wineItem) return FALSE; + prevSelect=infoPtr->selectedItem; + prevItem= TREEVIEW_ValidItem (infoPtr, prevSelect); + dummy.x=0; + dummy.y=0; + + action= (INT32) wParam; + + switch (action) { + case TVGN_CARET: + if (TREEVIEW_SendTreeviewNotify (wndPtr, TVN_SELCHANGING, TVC_BYMOUSE, + prevSelect, newSelect,dummy)) + return FALSE; /* FIXME: OK? */ + + if (prevItem) prevItem->state &= ~TVIS_SELECTED; + infoPtr->selectedItem=newSelect; + wineItem->state |=TVIS_SELECTED; + TREEVIEW_SendTreeviewNotify (wndPtr, TVN_SELCHANGED, + TVC_BYMOUSE, prevSelect, newSelect, dummy); + break; + case TVGN_DROPHILITE: + FIXME (treeview, "DROPHILITE not implemented"); + break; + case TVGN_FIRSTVISIBLE: + FIXME (treeview, "FIRSTVISIBLE not implemented"); + break; + } + + TREEVIEW_QueueRefresh (wndPtr); + + return TRUE; +} + + + +/* FIXME: does KEYDOWN also send notifications?? If so, use + TREEVIEW_SelectItem. +*/ + + +static LRESULT +TREEVIEW_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + TREEVIEW_ITEM *prevItem,*newItem; + int prevSelect; + + + TRACE (treeview,"%x %lx",wParam, lParam); + prevSelect=infoPtr->selectedItem; + if (!prevSelect) return FALSE; + + prevItem= TREEVIEW_ValidItem (infoPtr, prevSelect); + + newItem=NULL; + switch (wParam) { + case VK_UP: + newItem=TREEVIEW_GetPrevListItem (infoPtr, prevItem); + if (!newItem) + newItem=& infoPtr->items[infoPtr->TopRootItem]; + break; + case VK_DOWN: + newItem=TREEVIEW_GetNextListItem (infoPtr, prevItem); + if (!newItem) newItem=prevItem; + break; + case VK_HOME: + newItem=& infoPtr->items[infoPtr->TopRootItem]; + break; + case VK_END: + newItem=TREEVIEW_GetLastListItem (infoPtr); + break; + case VK_PRIOR: + case VK_NEXT: + case VK_BACK: + case VK_RETURN: + FIXME (treeview, "%x not implemented\n", wParam); + break; + } + + if (!newItem) return FALSE; + + if (prevItem!=newItem) { + prevItem->state &= ~TVIS_SELECTED; + newItem->state |= TVIS_SELECTED; + infoPtr->selectedItem=newItem->hItem; + TREEVIEW_QueueRefresh (wndPtr); + return TRUE; + } + + return FALSE; +} + + + +static LRESULT +TREEVIEW_VScroll (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) + +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + int maxHeight; + + TRACE (treeview,"wp %x, lp %lx\n", wParam, lParam); + if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE; + + switch (LOWORD (wParam)) { + case SB_LINEUP: + if (!infoPtr->cy) return FALSE; + infoPtr->cy -= infoPtr->uRealItemHeight; + if (infoPtr->cy < 0) infoPtr->cy=0; + break; + case SB_LINEDOWN: + maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight; + if (infoPtr->cy == maxHeight) return FALSE; + infoPtr->cy += infoPtr->uRealItemHeight; + if (infoPtr->cy > maxHeight) + infoPtr->cy = maxHeight; + break; + case SB_PAGEUP: + if (!infoPtr->cy) return FALSE; + infoPtr->cy -= infoPtr->uVisibleHeight; + if (infoPtr->cy < 0) infoPtr->cy=0; + break; + case SB_PAGEDOWN: + maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight; + if (infoPtr->cy == maxHeight) return FALSE; + infoPtr->cy += infoPtr->uVisibleHeight; + if (infoPtr->cy > maxHeight) + infoPtr->cy = maxHeight; + break; + case SB_THUMBTRACK: + infoPtr->cy = HIWORD (wParam); + break; + + } + + TREEVIEW_QueueRefresh (wndPtr); + return TRUE; +} + +static LRESULT +TREEVIEW_HScroll (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(wndPtr); + + TRACE (treeview,"wp %lx, lp %x\n", lParam, wParam); + + if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE; + return TRUE; +} + + + + + LRESULT WINAPI + TREEVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) + { + WND *wndPtr = WIN_FindWndPtr(hwnd); + + + switch (uMsg) { + case TVM_INSERTITEM32A: + return TREEVIEW_InsertItem32A (wndPtr, wParam, lParam); + + case TVM_INSERTITEM32W: + FIXME (treeview, "Unimplemented msg TVM_INSERTITEM32W\n"); + return 0; + + case TVM_DELETEITEM: + return TREEVIEW_DeleteItem (wndPtr, wParam, lParam); + + case TVM_EXPAND: + return TREEVIEW_Expand (wndPtr, wParam, lParam); + + case TVM_GETITEMRECT: + return TREEVIEW_GetItemRect (wndPtr, wParam, lParam); + + case TVM_GETCOUNT: + return TREEVIEW_GetCount (wndPtr, wParam, lParam); + + case TVM_GETINDENT: + return TREEVIEW_GetIndent (wndPtr, wParam, lParam); + + case TVM_SETINDENT: + return TREEVIEW_SetIndent (wndPtr, wParam, lParam); + + case TVM_GETIMAGELIST: + return TREEVIEW_GetImageList (wndPtr, wParam, lParam); + + case TVM_SETIMAGELIST: + return TREEVIEW_SetImageList (wndPtr, wParam, lParam); + + case TVM_GETNEXTITEM: + return TREEVIEW_GetNextItem32 (wndPtr, wParam, lParam); + + case TVM_SELECTITEM: + return TREEVIEW_SelectItem (wndPtr, wParam, lParam); + + case TVM_GETITEM32A: + return TREEVIEW_GetItem (wndPtr, wParam, lParam); + + case TVM_GETITEM32W: + FIXME (treeview, "Unimplemented msg TVM_GETITEM32W\n"); + return 0; + + case TVM_SETITEM32A: + return TREEVIEW_SetItem (wndPtr, wParam, lParam); + + case TVM_SETITEM32W: + FIXME (treeview, "Unimplemented msg TVM_SETITEMW\n"); + return 0; + + case TVM_EDITLABEL32A: + FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32A \n"); + return 0; + + case TVM_EDITLABEL32W: + FIXME (treeview, "Unimplemented msg TVM_EDITLABEL32W \n"); + return 0; + + case TVM_GETEDITCONTROL: + FIXME (treeview, "Unimplemented msg TVM_GETEDITCONTROL\n"); + return 0; + + case TVM_GETVISIBLECOUNT: + return TREEVIEW_GetVisibleCount (wndPtr, wParam, lParam); + + case TVM_HITTEST: + return TREEVIEW_HitTest32 (wndPtr, lParam); + + case TVM_CREATEDRAGIMAGE: + FIXME (treeview, "Unimplemented msg TVM_CREATEDRAGIMAGE\n"); + return 0; + + case TVM_SORTCHILDREN: + FIXME (treeview, "Unimplemented msg TVM_SORTCHILDREN\n"); + return 0; + + case TVM_ENSUREVISIBLE: + FIXME (treeview, "Unimplemented msg TVM_ENSUREVISIBLE\n"); + return 0; + + case TVM_SORTCHILDRENCB: + FIXME (treeview, "Unimplemented msg TVM_SORTCHILDRENCB\n"); + return 0; + + case TVM_ENDEDITLABELNOW: + FIXME (treeview, "Unimplemented msg TVM_ENDEDITLABELNOW\n"); + return 0; + + case TVM_GETISEARCHSTRING32A: + FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32A\n"); + return 0; + + case TVM_GETISEARCHSTRING32W: + FIXME (treeview, "Unimplemented msg TVM_GETISEARCHSTRING32W\n"); + return 0; + + case TVM_SETTOOLTIPS: + FIXME (treeview, "Unimplemented msg TVM_SETTOOLTIPS\n"); + return 0; + + case TVM_GETTOOLTIPS: + FIXME (treeview, "Unimplemented msg TVM_GETTOOLTIPS\n"); + return 0; + + case TVM_SETINSERTMARK: + FIXME (treeview, "Unimplemented msg TVM_SETINSERTMARK\n"); + return 0; + + case TVM_SETITEMHEIGHT: + return TREEVIEW_SetItemHeight (wndPtr, wParam); + + case TVM_GETITEMHEIGHT: + return TREEVIEW_GetItemHeight (wndPtr); + + case TVM_SETBKCOLOR: + FIXME (treeview, "Unimplemented msg TVM_SETBKCOLOR\n"); + return 0; + + case TVM_SETTEXTCOLOR: + return TREEVIEW_SetTextColor (wndPtr, wParam, lParam); + + case TVM_GETBKCOLOR: + FIXME (treeview, "Unimplemented msg TVM_GETBKCOLOR\n"); + return 0; + + case TVM_GETTEXTCOLOR: + return TREEVIEW_GetTextColor (wndPtr); + + case TVM_SETSCROLLTIME: + FIXME (treeview, "Unimplemented msg TVM_SETSCROLLTIME\n"); + return 0; + + case TVM_GETSCROLLTIME: + FIXME (treeview, "Unimplemented msg TVM_GETSCROLLTIME\n"); + return 0; + + case TVM_SETINSERTMARKCOLOR: + FIXME (treeview, "Unimplemented msg TVM_SETINSERTMARKCOLOR\n"); + return 0; + + case TVM_SETUNICODEFORMAT: + FIXME (treeview, "Unimplemented msg TVM_SETUNICODEFORMAT\n"); + return 0; + + case TVM_GETUNICODEFORMAT: + FIXME (treeview, "Unimplemented msg TVM_GETUNICODEFORMAT\n"); + return 0; + +// case WM_COMMAND: + + case WM_CREATE: + return TREEVIEW_Create (wndPtr, wParam, lParam); + + case WM_DESTROY: + return TREEVIEW_Destroy (wndPtr); + +// case WM_ENABLE: + + case WM_ERASEBKGND: + return TREEVIEW_EraseBackground (wndPtr, wParam, lParam); + + case WM_GETDLGCODE: + return DLGC_WANTARROWS | DLGC_WANTCHARS; + + case WM_PAINT: + return TREEVIEW_Paint (wndPtr, wParam); + +// case WM_GETFONT: +// case WM_SETFONT: + + case WM_KEYDOWN: + return TREEVIEW_KeyDown (wndPtr, wParam, lParam); + + +// case WM_KILLFOCUS: +// case WM_SETFOCUS: + + + case WM_LBUTTONDOWN: + return TREEVIEW_LButtonDown (wndPtr, wParam, lParam); + + case WM_LBUTTONDBLCLK: + return TREEVIEW_LButtonDoubleClick (wndPtr, wParam, lParam); + + case WM_RBUTTONDOWN: + return TREEVIEW_RButtonDown (wndPtr, wParam, lParam); + + +// case WM_SYSCOLORCHANGE: +// case WM_STYLECHANGED: +// case WM_SETREDRAW: + + case WM_TIMER: + return TREEVIEW_HandleTimer (wndPtr, wParam, lParam); + +// case WM_SIZE: + case WM_HSCROLL: + return TREEVIEW_HScroll (wndPtr, wParam, lParam); + case WM_VSCROLL: + return TREEVIEW_VScroll (wndPtr, wParam, lParam); + + default: + if (uMsg >= WM_USER) FIXME (treeview, "Unknown msg %04x wp=%08x lp=%08lx\n", - uMsg, wParam, lParam); - return DefWindowProc32A (hwnd, uMsg, wParam, lParam); - } + uMsg, wParam, lParam); + return DefWindowProc32A (hwnd, uMsg, wParam, lParam); + } return 0; }
diff --git a/dlls/comctl32/updown.c b/dlls/comctl32/updown.c index e93b5ef..8ccc64a 100644 --- a/dlls/comctl32/updown.c +++ b/dlls/comctl32/updown.c
@@ -27,14 +27,12 @@ */ #include <stdlib.h> -#include <assert.h> -#include <string.h> #include "windows.h" +#include "commctrl.h" #include "winnls.h" #include "sysmetrics.h" #include "updown.h" #include "graphics.h" -#include "heap.h" #include "win.h" #include "debug.h" @@ -249,7 +247,7 @@ if (!(wndPtr->dwStyle & UDS_NOTHOUSANDS)) { char txt2[20], *src = txt1, *dst = txt2; if(len%3 > 0){ - strncpy(dst, src, len%3); + lstrcpyn32A (dst, src, len%3); dst += len%3; src += len%3; } @@ -597,9 +595,7 @@ return TRUE; case WM_CREATE: - infoPtr = - (UPDOWN_INFO*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(UPDOWN_INFO)); + infoPtr = (UPDOWN_INFO*)COMCTL32_Alloc (sizeof(UPDOWN_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; /* initialize the info struct */ @@ -618,9 +614,9 @@ case WM_DESTROY: if(infoPtr->AccelVect) - free(infoPtr->AccelVect); + COMCTL32_Free (infoPtr->AccelVect); - HeapFree (GetProcessHeap (), 0, infoPtr); + COMCTL32_Free (infoPtr); wndPtr->wExtra[0] = 0; TRACE(updown, "UpDown Ctrl destruction, hwnd=%04x\n", hwnd); @@ -715,13 +711,13 @@ case UDM_SETACCEL: TRACE(updown, "UpDown Ctrl new accel info, hwnd=%04x\n", hwnd); if(infoPtr->AccelVect){ - free(infoPtr->AccelVect); + COMCTL32_Free (infoPtr->AccelVect); infoPtr->AccelCount = 0; infoPtr->AccelVect = 0; } if(wParam==0) return TRUE; - infoPtr->AccelVect = malloc(wParam*sizeof(UDACCEL)); + infoPtr->AccelVect = COMCTL32_Alloc (wParam*sizeof(UDACCEL)); if(infoPtr->AccelVect==0) return FALSE; memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL)); @@ -816,9 +812,9 @@ default: if (message >= WM_USER) - WARN(updown, "unknown msg %04x wp=%04x lp=%08lx\n", - message, wParam, lParam ); - return DefWindowProc32A( hwnd, message, wParam, lParam ); + ERR (updown, "unknown msg %04x wp=%04x lp=%08lx\n", + message, wParam, lParam); + return DefWindowProc32A (hwnd, message, wParam, lParam); } return 0;