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/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;
}