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/Makefile.in b/dlls/Makefile.in
index 67e3a95..ea8bc46 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -1,6 +1,9 @@
SUBDIRS = \
comctl32 \
- shell32
+ psapi \
+ shell32 \
+ winaspi \
+ wnaspi32
all: $(SUBDIRS)
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;
diff --git a/dlls/psapi/Makefile.in b/dlls/psapi/Makefile.in
new file mode 100644
index 0000000..17c618b
--- /dev/null
+++ b/dlls/psapi/Makefile.in
@@ -0,0 +1,16 @@
+DEFS = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = psapi
+
+C_SRCS = \
+ psapi_main.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
+
diff --git a/dlls/psapi/psapi_main.c b/dlls/psapi/psapi_main.c
new file mode 100644
index 0000000..94bc7f6
--- /dev/null
+++ b/dlls/psapi/psapi_main.c
@@ -0,0 +1,301 @@
+/*
+ * PSAPI library
+ *
+ * Copyright 1998 Patrik Stridvall
+ */
+
+#include "windows.h"
+#include "winbase.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "debug.h"
+#include "psapi.h"
+
+#include <string.h>
+
+/***********************************************************************
+ * EmptyWorkingSet (PSAPI.1)
+ */
+BOOL32 WINAPI EmptyWorkingSet32(HANDLE32 hProcess)
+{
+ return SetProcessWorkingSetSize(hProcess, 0xFFFFFFFF, 0xFFFFFFFF);
+}
+
+/***********************************************************************
+ * EnumDeviceDrivers (PSAPI.2)
+ */
+BOOL32 WINAPI EnumDeviceDrivers(
+ LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded)
+{
+ FIXME(psapi, "(%p, %ld, %p): stub\n", lpImageBase, cb, lpcbNeeded);
+
+ if(lpcbNeeded)
+ *lpcbNeeded = 0;
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * EnumProcesses (PSAPI.3)
+ */
+BOOL32 WINAPI EnumProcesses(DWORD *lpidProcess, DWORD cb, DWORD *lpcbNeeded)
+{
+ FIXME(psapi, "(%p, %ld, %p): stub\n", lpidProcess,cb, lpcbNeeded);
+
+ if(lpcbNeeded)
+ *lpcbNeeded = 0;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * EnumProcessModules (PSAPI.4)
+ */
+BOOL32 WINAPI EnumProcessModules(
+ HANDLE32 hProcess, HMODULE32 *lphModule, DWORD cb, LPDWORD lpcbNeeded)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %ld, %p): stub\n",
+ hProcess, lphModule, cb, lpcbNeeded
+ );
+
+ if(lpcbNeeded)
+ *lpcbNeeded = 0;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetDeviceDriverBaseName32A (PSAPI.5)
+ */
+DWORD WINAPI GetDeviceDriverBaseName32A(
+ LPVOID ImageBase, LPSTR lpBaseName, DWORD nSize)
+{
+ FIXME(psapi, "(%p, %s, %ld): stub\n",
+ ImageBase, debugstr_a(lpBaseName), nSize
+ );
+
+ if(lpBaseName && nSize)
+ lpBaseName[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetDeviceDriverBaseName32W (PSAPI.6)
+ */
+DWORD WINAPI GetDeviceDriverBaseName32W(
+ LPVOID ImageBase, LPWSTR lpBaseName, DWORD nSize)
+{
+ FIXME(psapi, "(%p, %s, %ld): stub\n",
+ ImageBase, debugstr_w(lpBaseName), nSize
+ );
+
+ if(lpBaseName && nSize)
+ lpBaseName[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetDeviceDriverFileName32A (PSAPI.7)
+ */
+DWORD WINAPI GetDeviceDriverFileName32A(
+ LPVOID ImageBase, LPSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(%p, %s, %ld): stub\n",
+ ImageBase, debugstr_a(lpFilename), nSize
+ );
+
+ if(lpFilename && nSize)
+ lpFilename[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetDeviceDriverFileName32W (PSAPI.8)
+ */
+DWORD WINAPI GetDeviceDriverFileName32W(
+ LPVOID ImageBase, LPWSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(%p, %s, %ld): stub\n",
+ ImageBase, debugstr_w(lpFilename), nSize
+ );
+
+ if(lpFilename && nSize)
+ lpFilename[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetMappedFileName32A (PSAPI.9)
+ */
+DWORD WINAPI GetMappedFileName32A(
+ HANDLE32 hProcess, LPVOID lpv, LPSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %s, %ld): stub\n",
+ hProcess, lpv, debugstr_a(lpFilename), nSize
+ );
+
+ if(lpFilename && nSize)
+ lpFilename[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetMappedFileName32W (PSAPI.10)
+ */
+DWORD WINAPI GetMappedFileName32W(
+ HANDLE32 hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %s, %ld): stub\n",
+ hProcess, lpv, debugstr_w(lpFilename), nSize
+ );
+
+ if(lpFilename && nSize)
+ lpFilename[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetModuleBaseName32A (PSAPI.11)
+ */
+DWORD WINAPI GetModuleBaseName32A(
+ HANDLE32 hProcess, HMODULE32 hModule, LPSTR lpBaseName, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %s, %ld): stub\n",
+ hProcess, hModule, debugstr_a(lpBaseName), nSize
+ );
+
+ if(lpBaseName && nSize)
+ lpBaseName[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetModuleBaseName32W (PSAPI.12)
+ */
+DWORD WINAPI GetModuleBaseName32W(
+ HANDLE32 hProcess, HMODULE32 hModule, LPWSTR lpBaseName, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %s, %ld): stub\n",
+ hProcess, hModule, debugstr_w(lpBaseName), nSize);
+
+ if(lpBaseName && nSize)
+ lpBaseName[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetModuleFileNameEx32A (PSAPI.13)
+ */
+DWORD WINAPI GetModuleFileNameEx32A(
+ HANDLE32 hProcess, HMODULE32 hModule, LPSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x,hModule=0x%08x, %s, %ld): stub\n",
+ hProcess, hModule, debugstr_a(lpFilename), nSize
+ );
+
+ if(lpFilename&&nSize)
+ lpFilename[0]='\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetModuleFileNameEx32W (PSAPI.14)
+ */
+DWORD WINAPI GetModuleFileNameEx32W(
+ HANDLE32 hProcess, HMODULE32 hModule, LPWSTR lpFilename, DWORD nSize)
+{
+ FIXME(psapi, "(hProcess=0x%08x,hModule=0x%08x, %s, %ld): stub\n",
+ hProcess, hModule, debugstr_w(lpFilename), nSize
+ );
+
+ if(lpFilename && nSize)
+ lpFilename[0] = '\0';
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetModuleInformation32 (PSAPI.15)
+ */
+BOOL32 WINAPI GetModuleInformation32(
+ HANDLE32 hProcess, HMODULE32 hModule, LPMODULEINFO32 lpmodinfo, DWORD cb)
+{
+ FIXME(psapi, "(hProcess=0x%08x, hModule=0x%08x, %p, %ld): stub\n",
+ hProcess, hModule, lpmodinfo, cb
+ );
+
+ memset(lpmodinfo, 0, cb);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetProcessMemoryInfo32 (PSAPI.16)
+ */
+BOOL32 WINAPI GetProcessMemoryInfo32(
+ HANDLE32 Process, PPROCESS_MEMORY_COUNTERS32 ppsmemCounters, DWORD cb)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %ld): stub\n",
+ Process, ppsmemCounters, cb
+ );
+
+ memset(ppsmemCounters, 0, cb);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetWsChanges32 (PSAPI.17)
+ */
+BOOL32 WINAPI GetWsChanges32(
+ HANDLE32 hProcess, PPSAPI_WS_WATCH_INFORMATION32 lpWatchInfo, DWORD cb)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %ld): stub\n",
+ hProcess, lpWatchInfo, cb
+ );
+
+ memset(lpWatchInfo, 0, cb);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * InitializeProcessForWsWatch32 (PSAPI.18)
+ */
+BOOL32 WINAPI InitializeProcessForWsWatch32(HANDLE32 hProcess)
+{
+ FIXME(psapi, "(hProcess=0x%08x): stub\n", hProcess);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * QueryWorkingSet32 (PSAPI.?)
+ * FIXME
+ * I haven't been able to find the ordinal for this function,
+ * This means it can't be called from outside the DLL.
+ */
+BOOL32 WINAPI QueryWorkingSet32(HANDLE32 hProcess, LPVOID pv, DWORD cb)
+{
+ FIXME(psapi, "(hProcess=0x%08x, %p, %ld)", hProcess, pv, cb);
+
+ if(pv && cb)
+ ((DWORD *) pv)[0] = 0; /* Empty WorkingSet */
+
+ return TRUE;
+}
+
+
+
+
+
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 2a7f204..6a58119 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -8,6 +8,7 @@
C_SRCS = \
contmenu.c \
+ dataobject.c \
enumidlist.c \
folders.c \
pidl.c \
diff --git a/dlls/shell32/contmenu.c b/dlls/shell32/contmenu.c
index 9aa758c..9bca626 100644
--- a/dlls/shell32/contmenu.c
+++ b/dlls/shell32/contmenu.c
@@ -10,11 +10,6 @@
#include "shlobj.h"
#include "shell32_main.h"
-#define IDM_EXPLORE 0
-#define IDM_OPEN 1
-#define IDM_RENAME 2
-#define IDM_LAST IDM_RENAME
-
#define __T(x) x
#define _T(x) __T(x)
#define TEXT _T
@@ -132,8 +127,26 @@
TRACE(shell,"(%p)->()\n",cm);
return cm;
}
+/**************************************************************************
+* ICM_InsertItem()
+*/
+static void ICM_InsertItem (HMENU32 hmenu, UINT32 indexMenu, UINT32 wID, UINT32 fType, LPSTR dwTypeData, UINT32 fState)
+{ MENUITEMINFO32A mii;
-
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ if (fType == MFT_SEPARATOR)
+ { mii.fMask = MIIM_ID | MIIM_TYPE;
+ }
+ else
+ { mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+ mii.dwTypeData = dwTypeData;
+ mii.fState = MFS_ENABLED | MFS_DEFAULT;
+ }
+ mii.wID = wID;
+ mii.fType = fType;
+ InsertMenuItem32A( hmenu, indexMenu, TRUE, &mii);
+}
/**************************************************************************
* IContextMenu_QueryContextMenu()
*/
@@ -141,71 +154,28 @@
static HRESULT WINAPI IContextMenu_QueryContextMenu( LPCONTEXTMENU this, HMENU32 hmenu,
UINT32 indexMenu,UINT32 idCmdFirst,UINT32 idCmdLast,UINT32 uFlags)
{ BOOL32 fExplore ;
- MENUITEMINFO32A mii;
TRACE(shell,"(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",this, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
if(!(CMF_DEFAULTONLY & uFlags))
{ if(!this->bAllValues)
- { fExplore = uFlags & CMF_EXPLORE;
- if(fExplore)
- { ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
- mii.wID = idCmdFirst + IDM_EXPLORE;
- mii.fType = MFT_STRING;
- mii.dwTypeData = TEXT("&Explore");
- mii.fState = MFS_ENABLED | MFS_DEFAULT;
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
+ { fExplore = uFlags & CMF_EXPLORE;
+ if(fExplore)
+ { ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_EXPLORE, MFT_STRING, TEXT("&Explore"), MFS_ENABLED|MFS_DEFAULT);
+ ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_OPEN, MFT_STRING, TEXT("&Open"), MFS_ENABLED);
+ }
+ else
+ { ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_OPEN, MFT_STRING, TEXT("&Open"), MFS_ENABLED|MFS_DEFAULT);
+ ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_EXPLORE, MFT_STRING, TEXT("&Explore"), MFS_ENABLED);
+ }
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
- mii.wID = idCmdFirst + IDM_OPEN;
- mii.fType = MFT_STRING;
- mii.dwTypeData = TEXT("&Open");
- mii.fState = MFS_ENABLED;
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
- }
- else
- { ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
- mii.wID = idCmdFirst + IDM_OPEN;
- mii.fType = MFT_STRING;
- mii.dwTypeData = TEXT("&Open");
- mii.fState = MFS_ENABLED | MFS_DEFAULT;
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
-
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
- mii.wID = idCmdFirst + IDM_EXPLORE;
- mii.fType = MFT_STRING;
- mii.dwTypeData = TEXT("&Explore");
- mii.fState = MFS_ENABLED;
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
- }
-
- if(uFlags & CMF_CANRENAME)
- { ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE;
- mii.wID = 0;
- mii.fType = MFT_SEPARATOR;
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
-
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
- mii.wID = idCmdFirst + IDM_RENAME;
- mii.fType = MFT_STRING;
- mii.dwTypeData = TEXT("&Rename");
- mii.fState = (IContextMenu_CanRenameItems(this) ? MFS_ENABLED : MFS_DISABLED);
- InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii);
- }
- }
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1));
- }
+ if(uFlags & CMF_CANRENAME)
+ { ICM_InsertItem(hmenu, indexMenu++, 0, MFT_SEPARATOR, NULL, 0);
+ ICM_InsertItem(hmenu, indexMenu++, idCmdFirst+IDM_RENAME, MFT_STRING, TEXT("&Rename"), (IContextMenu_CanRenameItems(this) ? MFS_ENABLED : MFS_DISABLED));
+ }
+ }
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1));
+ }
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
}
@@ -230,41 +200,41 @@
switch(LOWORD(lpcmi->lpVerb))
{ case IDM_EXPLORE:
case IDM_OPEN:
- /* Find the first item in the list that is not a value. These commands
- should never be invoked if there isn't at least one key item in the list.*/
+ /* Find the first item in the list that is not a value. These commands
+ should never be invoked if there isn't at least one folder item in the list.*/
- for(i = 0; this->aPidls[i]; i++)
+ for(i = 0; this->aPidls[i]; i++)
{ if(!_ILIsValue(this->aPidls[i]))
- break;
- }
+ break;
+ }
- pidlTemp = ILCombine(this->pSFParent->mpidl, this->aPidls[i]);
- pidlFQ = ILCombine(this->pSFParent->mpidlNSRoot, pidlTemp);
- SHFree(pidlTemp);
+ pidlTemp = ILCombine(this->pSFParent->mpidl, this->aPidls[i]);
+ pidlFQ = ILCombine(this->pSFParent->mpidlNSRoot, pidlTemp);
+ SHFree(pidlTemp);
- ZeroMemory(&sei, sizeof(sei));
- sei.cbSize = sizeof(sei);
- sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
- sei.lpIDList = pidlFQ;
- sei.lpClass = TEXT("folder");
- sei.hwnd = lpcmi->hwnd;
- sei.nShow = SW_SHOWNORMAL;
+ ZeroMemory(&sei, sizeof(sei));
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+ sei.lpIDList = pidlFQ;
+ sei.lpClass = TEXT("folder");
+ sei.hwnd = lpcmi->hwnd;
+ sei.nShow = SW_SHOWNORMAL;
- if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE)
+ if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE)
{ sei.lpVerb = TEXT("explore");
- }
- else
- { sei.lpVerb = TEXT("open");
- }
- ShellExecuteEx32A(&sei);
- SHFree(pidlFQ);
- break;
-
+ }
+ else
+ { sei.lpVerb = TEXT("open");
+ }
+ ShellExecuteEx32A(&sei);
+ SHFree(pidlFQ);
+ break;
+
case IDM_RENAME:
- MessageBeep32(MB_OK);
- /*handle rename for the view here*/
- break;
- }
+ MessageBeep32(MB_OK);
+ /*handle rename for the view here*/
+ break;
+ }
return NOERROR;
}
@@ -361,9 +331,9 @@
TRACE(shell,"(%p)->(apidl=%p count=%u)\n",this, aPidls, uItemCount);
if(this->aPidls)
{ for(i = 0; i < uItemCount; i++)
- { this->aPidls[i] = ILClone(aPidls[i]);
- }
- return TRUE;
+ { this->aPidls[i] = ILClone(aPidls[i]);
+ }
+ return TRUE;
}
return FALSE;
}
diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c
new file mode 100644
index 0000000..f9f790f
--- /dev/null
+++ b/dlls/shell32/dataobject.c
@@ -0,0 +1,259 @@
+/*
+ * IEnumFORMATETC, IDataObject
+ *
+ * selecting and droping objects within the shell and/or common dialogs
+ *
+ * Copyright 1998 <juergen.schmied@metronet.de>
+ */
+#include "debug.h"
+#include "shlobj.h"
+#include "winerror.h"
+#include "shell32_main.h"
+/***********************************************************************
+* IEnumFORMATETC implementation
+*/
+static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj);
+static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this);
+static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this);
+static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed);
+static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt);
+static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this);
+static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum);
+
+static struct IEnumFORMATETC_VTable efvt =
+{ IEnumFORMATETC_QueryInterface,
+ IEnumFORMATETC_AddRef,
+ IEnumFORMATETC_Release,
+ IEnumFORMATETC_Next,
+ IEnumFORMATETC_Skip,
+ IEnumFORMATETC_Reset,
+ IEnumFORMATETC_Clone
+};
+
+extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
+{ LPENUMFORMATETC ef;
+ DWORD size=cfmt * sizeof(FORMATETC32);
+
+ ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
+ ef->ref=1;
+ ef->lpvtbl=&efvt;
+
+ ef->posFmt = 0;
+ ef->countFmt = cfmt;
+ ef->pFmt = SHAlloc (size);
+
+ if (ef->pFmt)
+ { memcpy(ef->pFmt, afmt, size);
+ }
+
+ TRACE(shell,"(%p)->()\n",ef);
+ return ef;
+}
+static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj)
+{ char xriid[50];
+ WINE_StringFromCLSID((LPCLSID)riid,xriid);
+ TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+ *ppvObj = NULL;
+
+ if(IsEqualIID(riid, &IID_IUnknown))
+ { *ppvObj = this;
+ }
+ else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
+ { *ppvObj = (IDataObject*)this;
+ }
+
+ if(*ppvObj)
+ { (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);
+ TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+ return S_OK;
+ }
+ TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+
+}
+static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+ return ++(this->ref);
+}
+static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
+{ TRACE(shell,"(%p)->()\n",this);
+ if (!--(this->ref))
+ { TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
+ if (this->pFmt)
+ { SHFree (this->pFmt);
+ }
+ HeapFree(GetProcessHeap(),0,this);
+ return 0;
+ }
+ return this->ref;
+}
+static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
+{ UINT32 cfetch;
+ HRESULT hres = S_FALSE;
+
+ TRACE (shell, "(%p)->()\n", this);
+
+ if (this->posFmt < this->countFmt)
+ { cfetch = this->countFmt - this->posFmt;
+ if (cfetch >= celt)
+ { cfetch = celt;
+ hres = S_OK;
+ }
+ memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
+ this->posFmt += cfetch;
+ }
+ else
+ { cfetch = 0;
+ }
+
+ if (pceltFethed)
+ { *pceltFethed = cfetch;
+ }
+
+ return hres;
+}
+static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt)
+{ FIXME (shell, "(%p)->(num=%lu)\n", this, celt);
+
+ this->posFmt += celt;
+ if (this->posFmt > this->countFmt)
+ { this->posFmt = this->countFmt;
+ return S_FALSE;
+ }
+ return S_OK;
+}
+static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
+{ FIXME (shell, "(%p)->()\n", this);
+
+ this->posFmt = 0;
+ return S_OK;
+}
+static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
+{ FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
+ return E_NOTIMPL;
+}
+
+/***********************************************************************
+* IDataObject implementation
+*/
+
+static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT, REFIID riid, LPVOID * ppvObj);
+static ULONG WINAPI IDataObject_AddRef (LPDATAOBJECT);
+static ULONG WINAPI IDataObject_Release (LPDATAOBJECT);
+static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium);
+static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium);
+static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT, LPFORMATETC32 pformatetc);
+static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
+static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease);
+static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
+static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
+static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT, DWORD dwConnection);
+static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT, IEnumSTATDATA **ppenumAdvise);
+
+static struct IDataObject_VTable dtovt =
+{ IDataObject_QueryInterface,
+ IDataObject_AddRef,
+ IDataObject_Release,
+ IDataObject_GetData,
+ IDataObject_GetDataHere,
+ IDataObject_QueryGetData,
+ IDataObject_GetCanonicalFormatEtc,
+ IDataObject_SetData,
+ IDataObject_EnumFormatEtc,
+ IDataObject_DAdvise,
+ IDataObject_DUnadvise,
+ IDataObject_EnumDAdvise
+};
+
+/**************************************************************************
+* IDataObject_Constructor
+*/
+LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER pcf, LPITEMIDLIST * apit, UINT32 cpit)
+{ LPDATAOBJECT dto;
+ dto=(LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject));
+ dto->ref=1;
+ dto->lpvtbl=&dtovt;
+ TRACE(shell,"(%p)->()\n",dto);
+ return dto;
+}
+/***************************************************************************
+* IDataObject_QueryInterface
+*/
+static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT this, REFIID riid, LPVOID * ppvObj)
+{ char xriid[50];
+ WINE_StringFromCLSID((LPCLSID)riid,xriid);
+ TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
+
+ *ppvObj = NULL;
+
+ if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
+ { *ppvObj = this;
+ }
+ else if(IsEqualIID(riid, &IID_IDataObject)) /*IDataObject*/
+ { *ppvObj = (IDataObject*)this;
+ }
+
+ if(*ppvObj)
+ { (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);
+ TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+ return S_OK;
+ }
+ TRACE(shell,"-- Interface: E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+}
+/**************************************************************************
+* IDataObject_AddRef
+*/
+static ULONG WINAPI IDataObject_AddRef(LPDATAOBJECT this)
+{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
+ return ++(this->ref);
+}
+/**************************************************************************
+* IDataObject_Release
+*/
+static ULONG WINAPI IDataObject_Release(LPDATAOBJECT this)
+{ TRACE(shell,"(%p)->()\n",this);
+ if (!--(this->ref))
+ { TRACE(shell," destroying IDataObject(%p)\n",this);
+ HeapFree(GetProcessHeap(),0,this);
+ return 0;
+ }
+ return this->ref;
+}
+static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT this, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
+{ FIXME (shell, "(%p)->()\n", this);
+ return E_NOTIMPL;
+}
diff --git a/dlls/shell32/enumidlist.c b/dlls/shell32/enumidlist.c
index 960d6ac..365be32 100644
--- a/dlls/shell32/enumidlist.c
+++ b/dlls/shell32/enumidlist.c
@@ -53,24 +53,26 @@
* IEnumIDList_Constructor
*/
-LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult)
+LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags)
{ LPENUMIDLIST lpeidl;
lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
+ if (! lpeidl)
+ return NULL;
+
lpeidl->ref = 1;
lpeidl->lpvtbl = &eidlvt;
lpeidl->mpFirst=NULL;
lpeidl->mpLast=NULL;
lpeidl->mpCurrent=NULL;
- TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult);
+ TRACE(shell,"(%p)->(%s flags=0x%08lx)\n",lpeidl,debugstr_a(lpszPath),dwFlags);
if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags))
- { if(pResult)
- { *pResult = E_OUTOFMEMORY;
- HeapFree(GetProcessHeap(),0,lpeidl);
- return NULL;
+ { if (lpeidl)
+ { HeapFree(GetProcessHeap(),0,lpeidl);
}
+ return NULL;
}
TRACE(shell,"-- (%p)->()\n",lpeidl);
@@ -214,7 +216,7 @@
CHAR szDriveName[4];
CHAR szPath[MAX_PATH];
- TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
+ TRACE(shell,"(%p)->(path=%s flags=0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);
if (lpszPath && lpszPath[0]!='\0')
{ strcpy(szPath, lpszPath);
diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c
index 75374f9..4373a3a 100644
--- a/dlls/shell32/folders.c
+++ b/dlls/shell32/folders.c
@@ -22,6 +22,7 @@
#include "winnls.h"
#include "winproc.h"
#include "commctrl.h"
+#include "pidl.h"
#include "shell32_main.h"
@@ -42,6 +43,24 @@
static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
static ULONG WINAPI IShellLink_Release(LPSHELLLINK);
+static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK, LPSTR,INT32, WIN32_FIND_DATA32A *, DWORD);
+static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK, LPITEMIDLIST *);
+static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK, LPCITEMIDLIST);
+static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK, LPSTR,INT32);
+static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK, LPCSTR);
+static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK, WORD *);
+static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK, WORD);
+static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK, INT32 *);
+static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK, INT32);
+static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK, LPSTR,INT32,INT32 *);
+static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK, LPCSTR,INT32);
+static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK, LPCSTR, DWORD);
+static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK, HWND32, DWORD);
+static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK, LPCSTR);
/***********************************************************************
@@ -144,28 +163,28 @@
* IShellLink Implementation
*/
-static struct IShellLink_VTable slvt = {
- IShellLink_QueryInterface,
- IShellLink_AddRef,
- IShellLink_Release,
- (void *)0xcafe0004,
- (void *)0xcafe0005,
- (void *)0xcafe0006,
- (void *)0xcafe0007,
- (void *)0xcafe0008,
- (void *)0xcafe0009,
- (void *)0xcafe0010,
- (void *)0xcafe0011,
- (void *)0xcafe0012,
- (void *)0xcafe0013,
- (void *)0xcafe0014,
- (void *)0xcafe0015,
- (void *)0xcafe0016,
- (void *)0xcafe0017,
- (void *)0xcafe0018,
- (void *)0xcafe0019,
- (void *)0xcafe0020,
- (void *)0xcafe0021
+static struct IShellLink_VTable slvt =
+{ IShellLink_QueryInterface,
+ IShellLink_AddRef,
+ IShellLink_Release,
+ IShellLink_GetPath,
+ IShellLink_GetIDList,
+ IShellLink_SetIDList,
+ IShellLink_GetDescription,
+ IShellLink_SetDescription,
+ IShellLink_GetWorkingDirectory,
+ IShellLink_SetWorkingDirectory,
+ IShellLink_GetArguments,
+ IShellLink_SetArguments,
+ IShellLink_GetHotkey,
+ IShellLink_SetHotkey,
+ IShellLink_GetShowCmd,
+ IShellLink_SetShowCmd,
+ IShellLink_GetIconLocation,
+ IShellLink_SetIconLocation,
+ IShellLink_SetRelativePath,
+ IShellLink_Resolve,
+ IShellLink_SetPath
};
/**************************************************************************
@@ -227,4 +246,85 @@
return this->ref;
}
+static HRESULT WINAPI IShellLink_GetPath(LPSHELLLINK this, LPSTR pszFile,INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags)
+{ FIXME(shell,"(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",this, pszFile, cchMaxPath, pfd, fFlags);
+ strncpy(pszFile,"c:\\foo.bar", cchMaxPath);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetIDList(LPSHELLLINK this, LPITEMIDLIST * ppidl)
+{ FIXME(shell,"(%p)->(ppidl=%p)\n",this, ppidl);
+ *ppidl = _ILCreateDesktop();
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetIDList(LPSHELLLINK this, LPCITEMIDLIST pidl)
+{ FIXME(shell,"(%p)->(pidl=%p)\n",this, pidl);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetDescription(LPSHELLLINK this, LPSTR pszName,INT32 cchMaxName)
+{ FIXME(shell,"(%p)->(%p len=%u)\n",this, pszName, cchMaxName);
+ strncpy(pszName,"Description, FIXME",cchMaxName);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetDescription(LPSHELLLINK this, LPCSTR pszName)
+{ FIXME(shell,"(%p)->(desc=%s)\n",this, pszName);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetWorkingDirectory(LPSHELLLINK this, LPSTR pszDir,INT32 cchMaxPath)
+{ FIXME(shell,"(%p)->()\n",this);
+ strncpy(pszDir,"c:\\", cchMaxPath);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetWorkingDirectory(LPSHELLLINK this, LPCSTR pszDir)
+{ FIXME(shell,"(%p)->(dir=%s)\n",this, pszDir);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetArguments(LPSHELLLINK this, LPSTR pszArgs,INT32 cchMaxPath)
+{ FIXME(shell,"(%p)->(%p len=%u)\n",this, pszArgs, cchMaxPath);
+ strncpy(pszArgs, "", cchMaxPath);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetArguments(LPSHELLLINK this, LPCSTR pszArgs)
+{ FIXME(shell,"(%p)->(args=%s)\n",this, pszArgs);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetHotkey(LPSHELLLINK this, WORD *pwHotkey)
+{ FIXME(shell,"(%p)->(%p)\n",this, pwHotkey);
+ *pwHotkey=0x0;
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetHotkey(LPSHELLLINK this, WORD wHotkey)
+{ FIXME(shell,"(%p)->(hotkey=%x)\n",this, wHotkey);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetShowCmd(LPSHELLLINK this, INT32 *piShowCmd)
+{ FIXME(shell,"(%p)->(%p)\n",this, piShowCmd);
+ *piShowCmd=0;
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetShowCmd(LPSHELLLINK this, INT32 iShowCmd)
+{ FIXME(shell,"(%p)->(showcmd=%x)\n",this, iShowCmd);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_GetIconLocation(LPSHELLLINK this, LPSTR pszIconPath,INT32 cchIconPath,INT32 *piIcon)
+{ FIXME(shell,"(%p)->(%p len=%u iicon=%p)\n",this, pszIconPath, cchIconPath, piIcon);
+ strncpy(pszIconPath,"shell32.dll",cchIconPath);
+ *piIcon=1;
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetIconLocation(LPSHELLLINK this, LPCSTR pszIconPath,INT32 iIcon)
+{ FIXME(shell,"(%p)->(path=%s iicon=%u)\n",this, pszIconPath, iIcon);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetRelativePath(LPSHELLLINK this, LPCSTR pszPathRel, DWORD dwReserved)
+{ FIXME(shell,"(%p)->(path=%s %lx)\n",this, pszPathRel, dwReserved);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_Resolve(LPSHELLLINK this, HWND32 hwnd, DWORD fFlags)
+{ FIXME(shell,"(%p)->(hwnd=%x flags=%lx)\n",this, hwnd, fFlags);
+ return NOERROR;
+}
+static HRESULT WINAPI IShellLink_SetPath(LPSHELLLINK this, LPCSTR pszFile)
+{ FIXME(shell,"(%p)->(path=%s)\n",this, pszFile);
+ return NOERROR;
+}
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c
index caed624..67ccd94 100644
--- a/dlls/shell32/pidl.c
+++ b/dlls/shell32/pidl.c
@@ -3,8 +3,9 @@
*
* Copyright 1998 Juergen Schmied
*
- * !!! currently work in progress on all classes !!!
- * <contact juergen.schmied@metronet.de, 980801>
+ * NOTES
+ * a pidl == NULL means desktop and is legal
+ *
*/
#include <ctype.h>
@@ -29,15 +30,24 @@
{ DWORD type;
CHAR * szData;
LPITEMIDLIST pidltemp = pidl;
- TRACE(pidl,"---------- pidl=%p \n", pidl);
- do
- { type = _ILGetDataPointer(pidltemp)->type;
- szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
+ if (! pidltemp)
+ { TRACE(pidl,"-------- pidl = NULL (Root)\n");
+ return;
+ }
+ TRACE(pidl,"-------- pidl=%p \n", pidl);
+ if (pidltemp->mkid.cb)
+ { do
+ { type = _ILGetDataPointer(pidltemp)->type;
+ szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
- TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
+ TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
- pidltemp = ILGetNext(pidltemp);
- } while (pidltemp->mkid.cb);
+ pidltemp = ILGetNext(pidltemp);
+ } while (pidltemp->mkid.cb);
+ return;
+ }
+ else
+ TRACE(pidl,"empty pidl (Desktop)\n");
}
/*************************************************************************
* ILGetDisplayName [SHELL32.15]
@@ -88,6 +98,8 @@
TRACE(pidl,"%p\n",pidl);
+ pdump(pidl);
+
if (!pidl)
return NULL;
@@ -104,8 +116,40 @@
* duplicates the first idlist of a complex pidl
*/
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
-{ FIXME(pidl,"pidl=%p\n",pidl);
- return NULL;
+{ DWORD len;
+ LPITEMIDLIST newpidl=NULL;
+ TRACE(pidl,"pidl=%p\n",pidl);
+
+ if (pidl)
+ { len = pidl->mkid.cb;
+ newpidl = (LPITEMIDLIST) SHAlloc (len+2);
+ if (newpidl)
+ { memcpy(newpidl,pidl,len);
+ ILGetNext(newpidl)->mkid.cb = 0x00;
+ }
+ }
+
+ return newpidl;
+}
+/*************************************************************************
+ * ILIsEqual [SHELL32.21]
+ *
+ */
+BOOL32 WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{ FIXME(pidl,"pidl1=%p pidl2=%p stub\n",pidl1, pidl2);
+ pdump (pidl1);
+ pdump (pidl2);
+ return FALSE;
+}
+/*************************************************************************
+ * ILFindChild [SHELL32.24]
+ *
+ */
+DWORD WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
+{ FIXME(pidl,"%p %p stub\n",pidl1,pidl2);
+ pdump (pidl1);
+ pdump (pidl2);
+ return 0;
}
/*************************************************************************
@@ -125,6 +169,9 @@
if(!pidl1 && !pidl2)
{ return NULL;
}
+
+ pdump (pidl1);
+ pdump (pidl2);
if(!pidl1)
{ pidlNew = ILClone(pidl2);
@@ -149,6 +196,18 @@
return pidlNew;
}
/*************************************************************************
+ * SHLogILFromFSIL [SHELL32.95]
+ *
+ * NOTES
+ * might be the prepending of MyComputer to a filesystem pidl (?)
+ */
+LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
+{ FIXME(pidl,"(pidl=%p)\n",pidl);
+ pdump(pidl);
+ return ILClone(pidl);
+}
+
+/*************************************************************************
* ILGetSize [SHELL32.152]
* gets the byte size of an idlist including zero terminator (pidl)
*
@@ -162,19 +221,19 @@
* exported by ordinal
*/
DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
-{ LPSHITEMID si = &(pidl->mkid);
- DWORD len=0;
+{ LPSHITEMID si = &(pidl->mkid);
+ DWORD len=0;
- TRACE(pidl,"pidl=%p\n",pidl);
+ /*TRACE(pidl,"pidl=%p\n",pidl);*/
- if (pidl)
- { while (si->cb)
- { len += si->cb;
- si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
- }
- len += 2;
+ if (pidl)
+ { while (si->cb)
+ { len += si->cb;
+ si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
+ }
+ len += 2;
}
-/* TRACE(pidl,"-- size=%lu\n",len);*/
+ /*TRACE(pidl,"-- size=%lu\n",len);*/
return len;
}
/*************************************************************************
@@ -191,7 +250,7 @@
LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
{ LPITEMIDLIST nextpidl;
- TRACE(pidl,"(pidl=%p)\n",pidl);
+/* TRACE(pidl,"(pidl=%p)\n",pidl);*/
if(pidl)
{ nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
return nextpidl;
@@ -210,8 +269,8 @@
* Destroys the passed in idlist!
*/
LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd)
-{ TRACE(pidl,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd);
- return NULL;
+{ FIXME(pidl,"(pidl=%p,pidl=%p,%08u)stub\n",pidl,item,bEnd);
+ return NULL;
}
/*************************************************************************
* ILFree [SHELL32.155]
@@ -222,10 +281,31 @@
* exported by ordinal
*/
DWORD WINAPI ILFree(LPVOID pidl)
-{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
- if (!pidl)
- return 0;
- return SHFree(pidl);
+{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
+ if (!pidl)
+ return 0;
+ return SHFree(pidl);
+}
+/*************************************************************************
+ * ILCreateFromPath [SHELL32.157]
+ *
+ */
+LPITEMIDLIST WINAPI ILCreateFromPath(LPSTR path)
+{ LPSHELLFOLDER shellfolder;
+ LPITEMIDLIST pidlnew;
+ CHAR pszTemp[MAX_PATH*2];
+ LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
+ DWORD pchEaten;
+
+ TRACE(pidl,"(path=%s)\n",path);
+
+ LocalToWideChar32(lpszDisplayName, path, MAX_PATH);
+
+ if (SHGetDesktopFolder(&shellfolder)==S_OK)
+ { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,0, NULL,lpszDisplayName,&pchEaten,&pidlnew,NULL);
+ shellfolder->lpvtbl->fnRelease(shellfolder);
+ }
+ return pidlnew;
}
/**************************************************************************
@@ -303,12 +383,12 @@
* _ILIsDrive()
* _ILIsFolder()
* _ILIsValue()
-*/
+ */
BOOL32 WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
{ TRACE(pidl,"(%p)\n",pidl);
if (! pidl)
- return FALSE;
+ return TRUE;
return ( pidl->mkid.cb == 0x00 );
}
@@ -695,7 +775,7 @@
{ if(!pidl)
{ return NULL;
}
- TRACE(pidl,"(%p)\n", pidl);
+/* TRACE(pidl,"(%p)\n", pidl);*/
return (LPPIDLDATA)(&pidl->mkid.abID);
}
/**************************************************************************
@@ -703,7 +783,7 @@
* gets a pointer to the string stored in the pidl
*/
LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
-{ TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);
+{/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
if(!pidldata)
{ return NULL;
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index ea39237..49753c5 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -89,9 +89,10 @@
* http://premium.microsoft.com/msdn/library/techart/msdn193.htm
*/
-void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4)
-{ FIXME(shell, "(%08x, %p, \"%s\", %08lx)\n",
- hwnd, code ? code : "(null)", cmd ? cmd : "(null)", arg4);
+void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
+{
+ FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
+ debugstr_a(cmd), arg4);
}
/*************************************************************************
@@ -108,10 +109,10 @@
BOOL32 WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2)
{ WARN(shell,"(%p,%p):semi-stub.\n",imglist1,imglist2);
if (imglist1)
- { *imglist1=ShellBigIconList;
+ { *imglist1=ShellSmallIconList;
}
if (imglist2)
- { *imglist2=ShellSmallIconList;
+ { *imglist2=ShellBigIconList;
}
return TRUE;
@@ -351,7 +352,7 @@
*
*/
LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
-{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
+{ FIXME (shell, "(0x%lx,%s): stub\n", (DWORD)lpbi, debugstr_a(lpbi->lpszTitle));
return NULL;
}
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
index bf78ba6..73db66a 100644
--- a/dlls/shell32/shellole.c
+++ b/dlls/shell32/shellole.c
@@ -239,7 +239,7 @@
return lpclf;
}
/**************************************************************************
- * IClassFactory::QueryInterface
+ * IClassFactory_QueryInterface
*/
static HRESULT WINAPI IClassFactory_QueryInterface(
LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj)
@@ -316,6 +316,9 @@
else if (IsEqualIID(riid, &IID_IContextMenu))
{ pObj = (IUnknown *)IContextMenu_Constructor(NULL, NULL, 0);
}
+ else if (IsEqualIID(riid, &IID_IDataObject))
+ { pObj = (IUnknown *)IDataObject_Constructor();
+ }
else
{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
return(E_NOINTERFACE);
diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c
index b8aa3f8..245bd7c 100644
--- a/dlls/shell32/shellord.c
+++ b/dlls/shell32/shellord.c
@@ -231,28 +231,26 @@
* PathCombine [SHELL32.37]
*
* NOTES
- * concat_paths(char*target,const char*add);
- * concats "target\\add" and writes them to target
+ * if lpszFile='.' skip it
*/
-LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2) {
- char buf[260];
- TRACE(shell,"%s %s\n",x1,x2);
- if (!x2 || !x2[0]) {
- lstrcpy32A(target,x1);
- return target;
+LPSTR WINAPI PathCombine(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
+{ TRACE(shell,"%s %s\n",lpszDir,lpszFile);
+
+ if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
+ { strcpy(szDest,lpszDir);
+ return szDest;
}
- lstrcpy32A(buf,x1);
- PathAddBackslash(buf); /* append \ if not there */
- lstrcat32A(buf,x2);
- lstrcpy32A(target,buf);
- return target;
+ strcpy(szDest,lpszDir);
+ PathAddBackslash(szDest);
+ strcat(szDest,lpszFile);
+ return szDest;
}
/*************************************************************************
* PathIsUNC [SHELL32.39]
*
* NOTES
- * isUNC(const char*path);
+ * PathIsUNC(char*path);
*/
BOOL32 WINAPI PathIsUNC(LPCSTR path) {
TRACE(shell,"%s\n",path);
@@ -260,6 +258,14 @@
return TRUE;
return FALSE;
}
+/*************************************************************************
+ * PathIsExe [SHELL32.43]
+ *
+ */
+BOOL32 WINAPI PathIsExe (LPCSTR path)
+{ TRACE(shell,"path=%s\n",path);
+ return FALSE;
+}
/*************************************************************************
* PathFileExists [SHELL32.45]
@@ -274,6 +280,17 @@
else
return TRUE;
}
+/*************************************************************************
+ * PathMatchSpec [SHELL32.46]
+ *
+ * NOTES
+ * used from COMDLG32
+ */
+
+BOOL32 WINAPI PathMatchSpec(LPSTR x, LPSTR y)
+{ FIXME(shell,"%s %s stub\n",x,y);
+ return TRUE;
+}
/*************************************************************************
* PathResolve [SHELL32.51]
@@ -417,7 +434,7 @@
*/
DWORD WINAPI
SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh,DWORD y,DWORD z)
-{ FIXME(shell,"(folder=%p,%08lx,%08lx):stub.\n",sh,y,z);
+{ FIXME(shell,"(SF=%p,pidl=%08lx,%08lx):stub.\n",sh,y,z);
return 0;
}
@@ -872,7 +889,8 @@
*/
BOOL32 WINAPI ShellExecuteEx32A (LPSHELLEXECUTEINFO32A sei)
{ CHAR szTemp[MAX_PATH];
- FIXME(shell,"%p stub\n",sei);
+
+ FIXME(shell,"(%p): stub\n",sei);
if (sei->fMask & SEE_MASK_IDLIST)
{ SHGetPathFromIDList32A (sei->lpIDList,szTemp);
diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c
index 5b03dcb..f78d3cc 100644
--- a/dlls/shell32/shlfolder.c
+++ b/dlls/shell32/shlfolder.c
@@ -4,7 +4,7 @@
* Copyright 1997 Marcus Meissner
* Copyright 1998 Juergen Schmied
*
- * !!! currently work in progress on all classes 980818 !!!
+ * !!! currently work in progress on all classes 980930 !!!
* <contact juergen.schmied@metronet.de>
*/
@@ -105,8 +105,8 @@
sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
sf->ref=1;
sf->lpvtbl=&sfvt;
- sf->mlpszFolder=NULL;
- sf->mpSFParent=pParent;
+ sf->mlpszFolder=NULL; /* path of the folder */
+ sf->mpSFParent=pParent; /* parrent shellfolder */
TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl);
@@ -114,24 +114,24 @@
sf->mpidl = ILClone(pidl);
sf->mpidlNSRoot = NULL;
- if(sf->mpidl) /* do we have a pidl?*/
+ if(sf->mpidl) /* do we have a pidl? */
{ dwSize = 0;
- if(sf->mpSFParent->mlpszFolder)
+ if(sf->mpSFParent->mlpszFolder) /* get the size of the parents path */
{ dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1;
+ TRACE(shell,"-- (%p)->(parent's path=%s)\n",sf, debugstr_a(sf->mpSFParent->mlpszFolder));
}
- dwSize += _ILGetFolderText(sf->mpidl,NULL,0);
+ dwSize += _ILGetFolderText(sf->mpidl,NULL,0); /* add the size of the foldername*/
sf->mlpszFolder = SHAlloc(dwSize);
if(sf->mlpszFolder)
{ *(sf->mlpszFolder)=0x00;
- if(sf->mpSFParent->mlpszFolder)
+ if(sf->mpSFParent->mlpszFolder) /* if the parent has a path, get it*/
{ strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
PathAddBackslash (sf->mlpszFolder);
}
_ILGetFolderText(sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
+ TRACE(shell,"-- (%p)->(my path=%s)\n",sf, debugstr_a(sf->mlpszFolder));
}
}
-
- TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
return sf;
}
/**************************************************************************
@@ -288,16 +288,15 @@
HWND32 hwndOwner,
DWORD dwFlags,
LPENUMIDLIST* ppEnumIDList)
-{ HRESULT hr;
- TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);
+{ TRACE(shell,"(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);
- *ppEnumIDList = NULL;
- *ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr);
- TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
- if(!*ppEnumIDList)
- { return hr;
- }
- return S_OK;
+ *ppEnumIDList = NULL;
+ *ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags);
+ TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
+ if(!*ppEnumIDList)
+ { return E_OUTOFMEMORY;
+ }
+ return S_OK;
}
/**************************************************************************
* IShellFolder_Initialize()
@@ -496,19 +495,21 @@
do
{ if (*pidltemp)
{ if (_ILIsDesktop( *pidltemp))
- { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+ { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK );
}
else if (_ILIsMyComputer( *pidltemp))
- { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
+ { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR
+ | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK );
}
else if (_ILIsDrive( *pidltemp))
- { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM);
+ { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
+ SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK );
}
else if (_ILIsFolder( *pidltemp))
- { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM );
+ { *rgfInOut |= ( SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_CAPABILITYMASK );
}
else if (_ILIsValue( *pidltemp))
- { *rgfInOut |= (SFGAO_FILESYSTEM);
+ { *rgfInOut |= (SFGAO_FILESYSTEM | SFGAO_CAPABILITYMASK );
}
}
pidltemp++;
@@ -624,17 +625,14 @@
TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName);
- if (!pidl)
- { return E_OUTOFMEMORY;
- }
-
szSpecial[0]=0x00;
szDrive[0]=0x00;
/* test if simple(relative) or complex(absolute) pidl */
pidlTemp = ILGetNext(pidl);
- if (pidlTemp->mkid.cb==0x00)
+ if (pidlTemp && pidlTemp->mkid.cb==0x00)
{ bSimplePidl = TRUE;
+ TRACE(shell,"-- simple pidl\n");
}
if (_ILIsDesktop( pidl))
{ strcpy (szText,"Desktop");
@@ -667,12 +665,15 @@
{ case SHGDN_NORMAL:
_ILGetPidlPath( pidl, szText, MAX_PATH);
break;
+
+ case SHGDN_INFOLDER | SHGDN_FORPARSING: /*fall thru*/
case SHGDN_INFOLDER:
pidlTemp = ILFindLastID(pidl);
if (pidlTemp)
{ _ILGetItemText( pidlTemp, szText, MAX_PATH);
}
break;
+
case SHGDN_FORPARSING:
if (bSimplePidl)
{ /* if the IShellFolder has parents, get the path from the
@@ -696,6 +697,7 @@
}
break;
default:
+ TRACE(shell,"--- wrong flags=%lx\n", dwFlags);
return E_INVALIDARG;
}
if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00))
@@ -706,7 +708,7 @@
}
}
- TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText);
+ TRACE(shell,"-- (%p)->(%s)\n",this,szText);
if(!(lpName))
{ return E_OUTOFMEMORY;
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index 3939b38..13322f5 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -1,10 +1,7 @@
/*
* ShellView
*
- * Copyright 1998 Juergen Schmied
- *
- * !!! currently work in progress on all classes 980801 !!!
- * <contact juergen.schmied@metronet.de>
+ * Copyright 1998 <juergen.schmied@metronet.de>
*/
#include <ctype.h>
@@ -48,6 +45,8 @@
static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);
+static BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW);
+
static struct IShellView_VTable svvt =
{ IShellView_QueryInterface,
IShellView_AddRef,
@@ -71,8 +70,17 @@
#define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
#define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
#define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
+#define ID_LISTVIEW 2000
+#define MENU_OFFSET 1
+#define MENU_MAX 100
+#define TOOLBAR_ID (L"SHELLDLL_DefView")
+//windowsx.h
+#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
+#define GET_WM_COMMAND_HWND(wp, lp) (HWND32)(lp)
+#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
+// winuser.h
+#define WM_SETTINGCHANGE WM_WININICHANGE
-#define TOOLBAR_ID (L"ShellView")
typedef struct
{ int idCommand;
int iImage;
@@ -87,6 +95,11 @@
{ {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
{-1, 0, 0, 0, 0, 0, 0}
};
+BOOL32 g_bViewKeys;
+BOOL32 g_bShowIDW;
+
+typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
+
/**************************************************************************
* IShellView_Constructor
*/
@@ -107,30 +120,70 @@
return sv;
}
/**************************************************************************
+* helperfunctions for communication with ICommDlgBrowser
+*
+*/
+static BOOL32 IsInCommDlg(LPSHELLVIEW this)
+{ return(this->pCommDlgBrowser != NULL);
+}
+static HRESULT IncludeObject(LPSHELLVIEW this, LPCITEMIDLIST pidl)
+{ if ( IsInCommDlg(this) )
+ { TRACE(shell,"ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
+ return (this->pCommDlgBrowser->lpvtbl->fnIncludeObject(this->pCommDlgBrowser, this, pidl));
+ }
+ return S_OK;
+}
+static HRESULT OnDefaultCommand(LPSHELLVIEW this)
+{ if (IsInCommDlg(this))
+ { TRACE(shell,"ICommDlgBrowser::OnDefaultCommand\n");
+ return (this->pCommDlgBrowser->lpvtbl->fnOnDefaultCommand(this->pCommDlgBrowser, this));
+ }
+ return S_FALSE;
+}
+static HRESULT OnStateChange(LPSHELLVIEW this, UINT32 uFlags)
+{ if (IsInCommDlg(this))
+ { TRACE(shell,"ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
+ return (this->pCommDlgBrowser->lpvtbl->fnOnStateChange(this->pCommDlgBrowser, this, uFlags));
+ }
+ return S_FALSE;
+}
+
+/**************************************************************************
* ShellView_CreateList()
*
-* NOTES
-* internal
*/
-#define ID_LISTVIEW 2000
BOOL32 ShellView_CreateList (LPSHELLVIEW this)
-{ DWORD dwStyle;
+{ DWORD dwStyle;
- TRACE(shell,"%p\n",this);
+ TRACE(shell,"%p\n",this);
- dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
- LVS_ICON | LVS_SHAREIMAGELISTS | LVS_EDITLABELS ;
+ dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_SHAREIMAGELISTS | LVS_EDITLABELS;
+ switch (this->FolderSettings.ViewMode)
+ { case FVM_ICON: dwStyle |= LVS_ICON; break;
+ case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
+ case FVM_LIST: dwStyle |= LVS_LIST; break;
+ case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
+ }
+ if (this->FolderSettings.fFlags && FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
+ /*if (this->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
+ if (this->FolderSettings.fFlags && FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
- this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,WC_LISTVIEW32A,NULL,dwStyle,
- 0,0,0,0,
- this->hWnd,(HMENU32)ID_LISTVIEW,shell32_hInstance,NULL);
+ this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,
+ WC_LISTVIEW32A,
+ NULL,
+ dwStyle,
+ 0,0,0,0,
+ this->hWnd,
+ (HMENU32)ID_LISTVIEW,
+ shell32_hInstance,
+ NULL);
- if(!this->hWndList)
- return FALSE;
+ if(!this->hWndList)
+ return FALSE;
-// UpdateShellSettings();
- return TRUE;
+ // UpdateShellSettings();
+ return TRUE;
}
/**************************************************************************
* ShellView_InitList()
@@ -177,7 +230,6 @@
ListView_SetImageList(this->hWndList, ShellSmallIconList, LVSIL_SMALL);
ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_NORMAL);
- ListView_SetBkColor(this->hWndList, 0x00800000 );
return TRUE;
}
@@ -188,13 +240,13 @@
* internal
*/
int CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
-{ LPSHELLFOLDER pFolder = (LPSHELLFOLDER)lpData;
+{ LPSHELLFOLDER pFolder = (LPSHELLFOLDER)lpData;
- TRACE(shell,"\n");
- if(!pFolder)
- return 0;
+ TRACE(shell,"\n");
+ if(!pFolder)
+ return 0;
- return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
+ return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
}
/**************************************************************************
@@ -223,12 +275,19 @@
lvItem.lParam = (LPARAM)ILClone(pidl); /*set the item's data*/
lvItem.pszText = LPSTR_TEXTCALLBACK32A; /*get text on a callback basis*/
lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
- ListView_InsertItem32A(this->hWndList, &lvItem); /*add the item*/
+ if ( S_OK == IncludeObject(this, ILClone(pidl) )) /* fixme free the pidl*/
+ { ListView_InsertItem32A(this->hWndList, &lvItem); /*add the item*/
+ }
+ else
+ { SHFree(pidl); /* not viewed */
+ }
+
}
/*sort the items*/
- ListView_SortItems(this->hWndList, ShellView_CompareItems, (LPARAM)this->pSFParent);
-
+ /* ListView_SortItems(this->hWndList, ShellView_CompareItems, (LPARAM)this->pSFParent);*/
+
+
/*turn the listview's redrawing back on and force it to draw*/
SendMessage32A(this->hWndList, WM_SETREDRAW, TRUE, 0);
InvalidateRect32(this->hWndList, NULL, TRUE);
@@ -246,43 +305,47 @@
*/
LRESULT ShellView_OnCreate(LPSHELLVIEW this)
{ TRACE(shell,"%p\n",this);
+
if(ShellView_CreateList(this))
{ if(ShellView_InitList(this))
{ ShellView_FillList(this);
}
}
+
return S_OK;
}
/**************************************************************************
* ShellView_OnSize()
*/
LRESULT ShellView_OnSize(LPSHELLVIEW this, WORD wWidth, WORD wHeight)
-{ TRACE(shell,"%p width=%u height=%u\n",this, wWidth,wHeight);
- //resize the ListView to fit our window
- if(this->hWndList)
- { MoveWindow32(this->hWndList, 0, 0, wWidth, wHeight, TRUE);
- }
- return S_OK;
+{ TRACE(shell,"%p width=%u height=%u\n",this, wWidth,wHeight);
+
+ /*resize the ListView to fit our window*/
+ if(this->hWndList)
+ { MoveWindow32(this->hWndList, 0, 0, wWidth, wHeight, TRUE);
+ }
+
+ return S_OK;
}
/**************************************************************************
* ShellView_BuildFileMenu()
*/
HMENU32 ShellView_BuildFileMenu(LPSHELLVIEW this)
-{ CHAR szText[MAX_PATH];
+{ CHAR szText[MAX_PATH];
MENUITEMINFO32A mii;
int nTools,i;
HMENU32 hSubMenu;
- TRACE(shell,"(%p) stub\n",this);
+ TRACE(shell,"(%p) semi-stub\n",this);
- hSubMenu = CreatePopupMenu32();
+ hSubMenu = CreatePopupMenu32();
if(hSubMenu)
{ /*get the number of items in our global array*/
for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
- //add the menu items
+ /*add the menu items*/
for(i = 0; i < nTools; i++)
- { strcpy(szText, "dummy 44");
+ { strcpy(szText, "dummy BuildFileMenu");
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
@@ -290,16 +353,16 @@
if(TBSTYLE_SEP != g_Tools[i].bStyle)
{ mii.fType = MFT_STRING;
- mii.fState = MFS_ENABLED;
- mii.dwTypeData = szText;
- mii.wID = g_Tools[i].idCommand;
- }
+ mii.fState = MFS_ENABLED;
+ mii.dwTypeData = szText;
+ mii.wID = g_Tools[i].idCommand;
+ }
else
- { mii.fType = MFT_SEPARATOR;
- }
- /* tack this item onto the end of the menu */
- InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii);
- }
+ { mii.fType = MFT_SEPARATOR;
+ }
+ /* tack this item onto the end of the menu */
+ InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii);
+ }
}
return hSubMenu;
}
@@ -367,6 +430,24 @@
}
}
/**************************************************************************
+* ShellView_UpdateMenu()
+*/
+LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU32 hMenu)
+{ TRACE(shell,"(%p)->(menu=0x%08x\n",this,hMenu);
+ CheckMenuItem32(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
+
+ if(ShellView_CanDoIDockingWindow(this))
+ { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
+ CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
+ }
+ else
+ { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+ CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
+ }
+ return 0;
+}
+
+/**************************************************************************
* ShellView_OnDeactivate()
*
* NOTES
@@ -391,64 +472,63 @@
*/
LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT32 uState)
{ OLEMENUGROUPWIDTHS32 omw = { {0, 0, 0, 0, 0, 0} };
- MENUITEMINFO32A mii;
- CHAR szText[MAX_PATH];
+ MENUITEMINFO32A mii;
+ CHAR szText[MAX_PATH];
TRACE(shell,"%p uState=%x\n",this,uState);
//don't do anything if the state isn't really changing
if(this->uState == uState)
{ return S_OK;
- }
+ }
ShellView_OnDeactivate(this);
//only do this if we are active
if(uState != SVUIA_DEACTIVATE)
{ //merge the menus
- this->hMenu = CreateMenu32();
+ this->hMenu = CreateMenu32();
if(this->hMenu)
{ this->pShellBrowser->lpvtbl->fnInsertMenusSB(this->pShellBrowser, this->hMenu, &omw);
- //build the top level menu
- //get the menu item's text
- strcpy(szText,"dummy 31");
+ /*build the top level menu get the menu item's text*/
+ strcpy(szText,"dummy 31");
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
- mii.fType = MFT_STRING;
- mii.fState = MFS_ENABLED;
- mii.dwTypeData = szText;
- mii.hSubMenu = ShellView_BuildFileMenu(this);
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
+ mii.fType = MFT_STRING;
+ mii.fState = MFS_ENABLED;
+ mii.dwTypeData = szText;
+ mii.hSubMenu = ShellView_BuildFileMenu(this);
- //insert our menu into the menu bar
- if(mii.hSubMenu)
- { InsertMenuItem32A(this->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
- }
+ /*insert our menu into the menu bar*/
+ if(mii.hSubMenu)
+ { InsertMenuItem32A(this->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
+ }
- //get the view menu so we can merge with it
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_SUBMENU;
+ /*get the view menu so we can merge with it*/
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_SUBMENU;
if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
{ ShellView_MergeViewMenu(this, mii.hSubMenu);
- }
+ }
- //add the items that should only be added if we have the focus
- if(SVUIA_ACTIVATE_FOCUS == uState)
+ /*add the items that should only be added if we have the focus*/
+ if(SVUIA_ACTIVATE_FOCUS == uState)
{ //get the file menu so we can merge with it
ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
+ mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
{ ShellView_MergeFileMenu(this, mii.hSubMenu);
- }
- }
- this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
+ }
+ }
+ this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
}
}
this->uState = uState;
@@ -462,18 +542,16 @@
* internal
*/
LRESULT ShellView_OnSetFocus(LPSHELLVIEW this)
-{ TRACE(shell,"%p\n",this);
- /* Tell the browser one of our windows has received the focus. This should always
- be done before merging menus (OnActivate merges the menus) if one of our
- windows has the focus.*/
- this->pShellBrowser->lpvtbl->fnOnViewWindowActive(this->pShellBrowser,this);
- ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS);
+{ TRACE(shell,"%p\n",this);
+ /* Tell the browser one of our windows has received the focus. This should always
+ be done before merging menus (OnActivate merges the menus) if one of our
+ windows has the focus.*/
+ this->pShellBrowser->lpvtbl->fnOnViewWindowActive(this->pShellBrowser,this);
+ ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS);
- return 0;
+ return 0;
}
-BOOL32 g_bViewKeys;
-BOOL32 g_bShowIDW;
/**************************************************************************
* ShellView_OnKillFocus()
*/
@@ -487,112 +565,85 @@
* ShellView_AddRemoveDockingWindow()
*/
BOOL32 ShellView_AddRemoveDockingWindow(LPSHELLVIEW this, BOOL32 bAdd)
-{ TRACE(shell,"(%p)->(badd=0x%08x) stub\n",this,bAdd);
- return FALSE;
-/*
- BOOL32 bReturn = FALSE;
- HRESULT32 hr;
- IServiceProvider *pSP;
-*/
+{ BOOL32 bReturn = FALSE;
+ HRESULT hr;
+ LPSERVICEPROVIDER pSP;
+ LPDOCKINGWINDOWFRAME pFrame;
+
+ FIXME(shell,"(%p)->(badd=0x%08x) stub\n",this,bAdd);
+
/* get the browser's IServiceProvider */
-/* hr = this->pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
+ hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
if(SUCCEEDED(hr))
- {
- IDockingWindowFrame *pFrame;
-*/
- /*get the IDockingWindowFrame pointer*/
-/*
- hr = pSP->QueryService(SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
- if(SUCCEEDED(hr))
- { if(bAdd)
- { hr = S_OK;
- if(!this->pDockingWindow)
- { //create the toolbar object
- this->pDockingWindow = new CDockingWindow(this, this->hWnd);
- }
-
- if(this->pDockingWindow)
- { //add the toolbar object
- hr = pFrame->AddToolbar((IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
-
- if(SUCCEEDED(hr))
- { bReturn = TRUE;
+ { /*get the IDockingWindowFrame pointer*/
+ hr = pSP->lpvtbl->fnQueryService(pSP, &SID_SShellBrowser, &IID_IDockingWindowFrame, (LPVOID*)&pFrame);
+ if(SUCCEEDED(hr))
+ { if(bAdd)
+ { hr = S_OK;
+ /*if(!this->pDockingWindow)
+ { //create the toolbar object
+ this->pDockingWindow = DockingWindow_Constructor(this, this->hWnd);
}
- }
- }
- else
- { if(this->pDockingWindow)
- { hr = pFrame->RemoveToolbar((IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL);
- if(SUCCEEDED(hr))
- {*/
- /* RemoveToolbar should release the toolbar object which will cause
- it to destroy itself. Our toolbar object is no longer valid at
- this point.*/
+ if(this->pDockingWindow)
+ { //add the toolbar object
+ hr = pFrame->lpvtbl->fnAddToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
+
+ if(SUCCEEDED(hr))
+ { bReturn = TRUE;
+ }
+ }*/
+ }
+ else
+ { /*if(this->pDockingWindow)
+ { hr = pFrame->->lpvtbl->fnRemoveToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL);
+
+ if(SUCCEEDED(hr))
+ { // RemoveToolbar should release the toolbar object which will cause
+ //it to destroy itself. Our toolbar object is no longer valid at
+ //this point.
-/* this->pDockingWindow = NULL;
- bReturn = TRUE;
- }
- }
+ this->pDockingWindow = NULL;
+ bReturn = TRUE;
+ }
+ }*/
}
- pFrame->Release();
- }
- pSP->Release();
+ pFrame->lpvtbl->fnRelease(pFrame);
+ }
+ pSP->lpvtbl->fnRelease(pSP);
}
- return bReturn;*/
+ return bReturn;
}
/**************************************************************************
* ShellView_CanDoIDockingWindow()
*/
BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW this)
-{ TRACE(shell,"(%p) stub\n",this);
- return FALSE;
-/*
- BOOL32 bReturn = FALSE;
- HRESULT32 hr;
- IServiceProvider *pSP;
- IDockingWindowFrame *pFrame;
-
- //get the browser's IServiceProvider
- hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
+{ BOOL32 bReturn = FALSE;
+ HRESULT hr;
+ LPSERVICEPROVIDER pSP;
+ LPDOCKINGWINDOWFRAME pFrame;
+
+ FIXME(shell,"(%p) stub\n",this);
+
+ /*get the browser's IServiceProvider*/
+ hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
if(hr==S_OK)
- { hr = pSP->lpvtbl->fnQueryService(pSP, SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
+ { hr = pSP->lpvtbl->fnQueryService(pSP, &SID_SShellBrowser, &IID_IDockingWindowFrame, (LPVOID*)&pFrame);
if(SUCCEEDED(hr))
- { bReturn = TRUE;
- pFrame->lpvtbl->fnRelease(pFrame);
- }
- pSP->lpvtbl->fnRelease(pSP);
+ { bReturn = TRUE;
+ pFrame->lpvtbl->fnRelease(pFrame);
+ }
+ pSP->lpvtbl->fnRelease(pSP);
}
- return bReturn;*/
-}
-/**************************************************************************
-* ShellView_UpdateMenu()
-*/
-LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU32 hMenu)
-{ TRACE(shell,"(%p)->(menu=0x%08x\n",this,hMenu);
- CheckMenuItem32(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
-
- if(ShellView_CanDoIDockingWindow(this))
- { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
- CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
- }
- else
- { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
- }
- return 0;
+ return bReturn;
}
/**************************************************************************
* ShellView_UpdateShellSettings()
-
-**************************************************************************/
-typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
-
-
+*/
void ShellView_UpdateShellSettings(LPSHELLVIEW this)
-{ TRACE(shell,"(%p) stub\n",this);
+{ FIXME(shell,"(%p) stub\n",this);
return ;
/*
SHELLFLAGSTATE sfs;
@@ -641,14 +692,12 @@
return 0;
}
-#define MENU_OFFSET 1
-#define MENU_MAX 100
-
/**************************************************************************
* ShellView_DoContextMenu()
*/
void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL32 fDefault)
-{ UINT32 uCommand, i, uSelected = ListView_GetSelectedCount(this->hWndList);
+{ UINT32 uCommand, i, uSelected = ListView_GetSelectedCount(this->hWndList);
+ DWORD wFlags;
HMENU32 hMenu;
BOOL32 fExplore = FALSE;
HWND32 hwndTree = 0;
@@ -663,7 +712,7 @@
aSelectedItems = (LPITEMIDLIST*)SHAlloc(uSelected * sizeof(LPITEMIDLIST));
if(aSelectedItems)
- { TRACE(shell,"-- aSelectedItems\n");
+ { TRACE(shell,"-- Items selected =%u\n", uSelected);
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_STATE | LVIF_PARAM;
lvItem.stateMask = LVIS_SELECTED;
@@ -675,19 +724,25 @@
{ if(lvItem.state & LVIS_SELECTED)
{ aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
i++;
+ TRACE(shell,"-- selected Item found\n");
}
lvItem.iItem++;
}
- this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent, this->hWndParent, uSelected,
- (LPCITEMIDLIST*)aSelectedItems, &IID_IContextMenu, NULL,(LPVOID*)&pContextMenu);
+ this->pSFParent->lpvtbl->fnGetUIObjectOf( this->pSFParent,
+ this->hWndParent,
+ uSelected,
+ (LPCITEMIDLIST*)aSelectedItems,
+ &IID_IContextMenu,
+ NULL,
+ (LPVOID*)&pContextMenu);
if(pContextMenu)
{ TRACE(shell,"-- pContextMenu\n");
hMenu = CreatePopupMenu32();
- /* See if we are in Explore or Open mode. If the browser's tree is present,
- then we are in Explore mode.*/
+ /* See if we are in Explore or Open mode. If the browser's tree is present,
+ then we are in Explore mode.*/
fExplore = FALSE;
hwndTree = 0;
@@ -696,10 +751,12 @@
fExplore = TRUE;
}
- if(hMenu && SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu(pContextMenu,
- hMenu,0,MENU_OFFSET,MENU_MAX,CMF_NORMAL |
- (uSelected != 1 ? 0 : CMF_CANRENAME) |
- (fExplore ? CMF_EXPLORE : 0))))
+ if(hMenu && SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu( pContextMenu,
+ hMenu,
+ 0,
+ MENU_OFFSET,
+ MENU_MAX,
+ CMF_NORMAL | (uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0))))
{ if(fDefault)
{ TRACE(shell,"-- fDefault\n");
uCommand = 0;
@@ -725,16 +782,31 @@
}
if(uCommand > 0)
- { TRACE(shell,"-- ! uCommand\n");
- ZeroMemory(&cmi, sizeof(cmi));
- cmi.cbSize = sizeof(cmi);
- cmi.hwnd = this->hWndParent;
- cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET);
+ { TRACE(shell,"-- uCommand=%u\n", uCommand);
+ if (((uCommand-MENU_OFFSET) == IDM_EXPLORE) || ((uCommand-MENU_OFFSET) == IDM_OPEN))
+ { if (IsInCommDlg(this)) /* are we part of a commctrl? */
+ { TRACE(shell,"-- fnOnDefaultCommand\n");
+ OnDefaultCommand(this);
+ }
+ else /* we are acting with a full featured IShellBrowser */
+ { TRACE(shell,"-- fnBrowseObject pidl =%p\n", aSelectedItems[0]);
+ wFlags = SBSP_DEFBROWSER | SBSP_DEFMODE | SBSP_RELATIVE;
+ this->pShellBrowser->lpvtbl->fnBrowseObject( this->pShellBrowser,
+ aSelectedItems[0],
+ wFlags);
+ }
+ }
+ else
+ { ZeroMemory(&cmi, sizeof(cmi));
+ cmi.cbSize = sizeof(cmi);
+ cmi.hwnd = this->hWndParent;
+ cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET);
pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi);
+ }
}
DestroyMenu32(hMenu);
}
- pContextMenu->lpvtbl->fnRelease(pContextMenu);
+ pContextMenu->lpvtbl->fnRelease(pContextMenu);
}
SHFree(aSelectedItems);
}
@@ -761,7 +833,7 @@
break;
default:
- FIXME(shell,"-- unknown command\n");
+ FIXME(shell,"-- COMMAND unhandled\n");
}
return 0;
}
@@ -782,44 +854,45 @@
TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",this,CtlID,lpnmh->code);
switch(lpnmh->code)
- { case NM_SETFOCUS:
- TRACE(shell,"NM_SETFOCUS %p\n",this);
+ { case NM_SETFOCUS:
+ TRACE(shell,"-- NM_SETFOCUS %p\n",this);
ShellView_OnSetFocus(this);
break;
case NM_KILLFOCUS:
- TRACE(shell,"NM_KILLFOCUS %p\n",this);
+ TRACE(shell,"-- NM_KILLFOCUS %p\n",this);
ShellView_OnDeactivate(this);
break;
case HDN_ENDTRACK32A:
- TRACE(shell,"HDN_ENDTRACK32A %p\n",this);
+ TRACE(shell,"-- HDN_ENDTRACK32A %p\n",this);
/*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0);
nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/
- return 0;
+ break;
case LVN_DELETEITEM:
- TRACE(shell,"LVN_DELETEITEM %p\n",this);
+ TRACE(shell,"-- LVN_DELETEITEM %p\n",this);
SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
break;
-#ifdef LVN_ITEMACTIVATE
- case LVN_ITEMACTIVATE:
-#else
case NM_DBLCLK:
case NM_RETURN:
-#endif
- TRACE(shell,"LVN_ITEMACTIVATE | NM_RETURN %p\n",this);
+ TRACE(shell,"-- NM_RETURN|NM_DBLCLK ignored, waiting for LVN_ITEMACTIVATE\n");
+ break;
+
+ case LVN_ITEMACTIVATE:
+ TRACE(shell,"-- LVN_ITEMACTIVATE %p\n",this);
ShellView_DoContextMenu(this, 0, 0, TRUE);
- return 0;
+ break;
case NM_RCLICK:
- TRACE(shell,"NM_RCLICK %p\n",this);
+ TRACE(shell,"-- NM_RCLICK %p\n",this);
dwCursor = GetMessagePos();
ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
+ break;
case LVN_GETDISPINFO32A:
- TRACE(shell,"LVN_GETDISPINFO32A %p\n",this);
+ TRACE(shell,"-- LVN_GETDISPINFO32A %p\n",this);
pidl = (LPITEMIDLIST)lpdi->item.lParam;
@@ -858,27 +931,40 @@
}
}
TRACE(shell,"-- text=%s image=%x\n",lpdi->item.pszText, lpdi->item.iImage);
- return 0;
+ break;
case NM_CLICK:
- TRACE(shell,"NM_CLICK %p\n",this);
+ WARN(shell,"-- NM_CLICK %p\n",this);
break;
case LVN_ITEMCHANGING:
- TRACE(shell,"LVN_ITEMCHANGING %p\n",this);
+ WARN(shell,"-- LVN_ITEMCHANGING %p\n",this);
break;
case LVN_ITEMCHANGED:
- TRACE(shell,"LVN_ITEMCHANGED %p\n",this);
+ WARN(shell,"-- LVN_ITEMCHANGED %p\n",this);
+ OnStateChange(this, CDBOSC_SELCHANGE);
+ break;
+
+ case LVN_DELETEALLITEMS:
+ WARN(shell,"-- LVN_DELETEALLITEMS %p\n",this);
+ break;
+
+ case LVN_INSERTITEM:
+ WARN(shell,"-- LVN_INSERTITEM %p\n",this);
+ break;
+
+ case LVN_BEGINDRAG:
+ WARN(shell,"-- LVN_BEGINDRAG %p\n",this);
break;
case NM_CUSTOMDRAW:
- TRACE(shell,"NM_CUSTOMDRAW %p\n",this);
+ WARN(shell,"NM_CUSTOMDRAW %p\n",this);
break;
default:
- WARN (shell,"-- WM_NOTIFY unhandled\n");
- return 0;
+ FIXME (shell,"-- WM_NOTIFY unhandled\n");
+ break;;
}
return 0;
}
@@ -886,23 +972,17 @@
/**************************************************************************
* ShellView_WndProc
*/
-//windowsx.h
-#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
-#define GET_WM_COMMAND_HWND(wp, lp) (HWND32)(lp)
-#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
-// winuser.h
-#define WM_SETTINGCHANGE WM_WININICHANGE
LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam)
{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA);
LPCREATESTRUCT32A lpcs;
DWORD dwCursor;
- FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
+ TRACE(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
switch (uMessage)
{ case WM_NCCREATE:
- { TRACE(shell,"WM_NCCREATE\n");
+ { TRACE(shell,"-- WM_NCCREATE\n");
lpcs = (LPCREATESTRUCT32A)lParam;
pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);
@@ -911,87 +991,50 @@
break;
case WM_SIZE:
- TRACE(shell,"WM_SIZE\n");
+ TRACE(shell,"-- WM_SIZE\n");
return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
case WM_SETFOCUS:
- TRACE(shell,"WM_SETFOCUS\n");
+ TRACE(shell,"-- WM_SETFOCUS\n");
return ShellView_OnSetFocus(pThis);
case WM_KILLFOCUS:
- TRACE(shell,"WM_KILLFOCUS\n");
+ TRACE(shell,"-- WM_KILLFOCUS\n");
return ShellView_OnKillFocus(pThis);
case WM_CREATE:
- TRACE(shell,"WM_CREATE\n");
+ TRACE(shell,"-- WM_CREATE\n");
return ShellView_OnCreate(pThis);
case WM_SHOWWINDOW:
- TRACE(shell,"WM_SHOWWINDOW\n");
+ TRACE(shell,"-- WM_SHOWWINDOW\n");
UpdateWindow32(pThis->hWndList);
break;
case WM_ACTIVATE:
- TRACE(shell,"WM_ACTIVATE\n");
+ TRACE(shell,"-- WM_ACTIVATE\n");
return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
case WM_COMMAND:
- TRACE(shell,"WM_COMMAND\n");
+ TRACE(shell,"-- WM_COMMAND\n");
return ShellView_OnCommand(pThis, GET_WM_COMMAND_ID(wParam, lParam),
GET_WM_COMMAND_CMD(wParam, lParam),
GET_WM_COMMAND_HWND(wParam, lParam));
case WM_INITMENUPOPUP:
- TRACE(shell,"WM_INITMENUPOPUP\n");
+ TRACE(shell,"-- WM_INITMENUPOPUP\n");
return ShellView_UpdateMenu(pThis, (HMENU32)wParam);
case WM_NOTIFY:
- TRACE(shell,"WM_NOTIFY\n");
+ TRACE(shell,"-- WM_NOTIFY\n");
return ShellView_OnNotify(pThis,(UINT32)wParam, (LPNMHDR)lParam);
case WM_SETTINGCHANGE:
- TRACE(shell,"WM_SETTINGCHANGE\n");
+ TRACE(shell,"-- WM_SETTINGCHANGE\n");
return ShellView_OnSettingChange(pThis,(LPCSTR)lParam);
-/* -------------*/
- case WM_MOVE:
- TRACE(shell,"WM_MOVE\n");
- break;
-
- case WM_ACTIVATEAPP:
- TRACE(shell,"WM_ACTIVATEAPP\n");
- break;
-
- case WM_NOTIFYFORMAT:
- TRACE(shell,"WM_NOTIFYFORMAT\n");
- break;
-
- case WM_NCPAINT:
- TRACE(shell,"WM_NCPAINT\n");
- break;
-
- case WM_ERASEBKGND:
- TRACE(shell,"WM_ERASEBKGND\n");
- break;
-
- case WM_PAINT:
- TRACE(shell,"WM_PAINT\n");
- break;
-
- case WM_NCCALCSIZE:
- TRACE(shell,"WM_NCCALCSIZE\n");
- break;
-
- case WM_WINDOWPOSCHANGING:
- TRACE(shell,"WM_WINDOWPOSCHANGING\n");
- break;
-
- case WM_WINDOWPOSCHANGED:
- TRACE(shell,"WM_WINDOWPOSCHANGED\n");
- break;
-
case WM_PARENTNOTIFY:
- TRACE(shell,"WM_PARENTNOTIFY\n");
+ TRACE(shell,"-- WM_PARENTNOTIFY\n");
if ( LOWORD(wParam) == WM_RBUTTONDOWN ) /* fixme: should not be handled here*/
{ dwCursor = GetMessagePos();
ShellView_DoContextMenu(pThis, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
@@ -999,19 +1042,92 @@
}
break;
+/* -------------*/
+ case WM_MOVE:
+ WARN(shell,"-- WM_MOVE\n");
+ break;
+
+ case WM_ACTIVATEAPP:
+ WARN(shell,"-- WM_ACTIVATEAPP\n");
+ break;
+
+ case WM_NOTIFYFORMAT:
+ WARN(shell,"-- WM_NOTIFYFORMAT\n");
+ break;
+
+ case WM_NCPAINT:
+ WARN(shell,"-- WM_NCPAINT\n");
+ break;
+
+ case WM_ERASEBKGND:
+ WARN(shell,"-- WM_ERASEBKGND\n");
+ break;
+
+ case WM_PAINT:
+ WARN(shell,"-- WM_PAINT\n");
+ break;
+
+ case WM_NCCALCSIZE:
+ WARN(shell,"-- WM_NCCALCSIZE\n");
+ break;
+
+ case WM_WINDOWPOSCHANGING:
+ WARN(shell,"-- WM_WINDOWPOSCHANGING\n");
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ WARN(shell,"-- WM_WINDOWPOSCHANGED\n");
+ break;
+
case WM_MOUSEACTIVATE:
- TRACE(shell,"WM_MOUSEACTIVATE\n");
+ WARN(shell,"-- WM_MOUSEACTIVATE\n");
break;
case WM_SETCURSOR:
- TRACE(shell,"WM_SETCURSOR\n");
+ WARN(shell,"-- WM_SETCURSOR\n");
+ break;
+
+ case WM_DESTROY:
+ WARN(shell,"-- WM_DESTROY\n");
+ break;
+
+ case WM_NCDESTROY:
+ WARN(shell,"-- WM_NCDESTROY\n");
+ break;
+
+ case WM_CONTEXTMENU:
+ WARN(shell,"-- WM_CONTEXTMENU\n");
+ break;
+
+ case WM_MENUSELECT:
+ WARN(shell,"-- WM_MENUSELECT\n");
+ break;
+
+ case WM_CAPTURECHANGED:
+ WARN(shell,"-- WM_CAPTURECHANGED\n");
+ break;
+
+ case WM_CHILDACTIVATE:
+ WARN(shell,"-- WM_CHILDACTIVATE\n");
+ break;
+
+ case WM_ENTERIDLE:
+ WARN(shell,"-- WM_ENTERIDLE\n");
+ break;
+
+ default:
+ FIXME(shell,"-- MESSAGE unhandled\n");
break;
}
return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
}
-
-
/**************************************************************************
+*
+*
+* The INTERFACE of the IShellView object
+*
+*
+***************************************************************************
* IShellView::QueryInterface
*/
static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
@@ -1049,7 +1165,7 @@
static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
{ TRACE(shell,"(%p)->()\n",this);
if (!--(this->ref))
- { TRACE(shell," destroying IEnumIDList(%p)\n",this);
+ { TRACE(shell," destroying IShellView(%p)\n",this);
if(this->pSFParent)
this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
@@ -1063,10 +1179,10 @@
* ShellView_GetWindow
*/
static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
-{ TRACE(shell,"(%p) stub\n",this);
- *phWnd = this->hWnd;
+{ TRACE(shell,"(%p) stub\n",this);
+ *phWnd = this->hWnd;
- return S_OK;
+ return S_OK;
}
static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
{ FIXME(shell,"(%p) stub\n",this);
@@ -1095,94 +1211,114 @@
LRESULT lResult;
int nPartArray[1] = {-1};
- FIXME(shell,"(%p) stub\n",this);
- //don't do anything if the state isn't really changing
+ FIXME(shell,"(%p)->(state=%x) stub\n",this, uState);
+ /*don't do anything if the state isn't really changing*/
if(this->uState == uState)
{ return S_OK;
- }
+ }
- //OnActivate handles the menu merging and internal state
+ /*OnActivate handles the menu merging and internal state*/
ShellView_OnActivate(this, uState);
- //remove the docking window
+ /*remove the docking window*/
if(g_bShowIDW)
{ ShellView_AddRemoveDockingWindow(this, FALSE);
- }
+ }
- //only do this if we are active
+ /*only do this if we are active*/
if(uState != SVUIA_DEACTIVATE)
{ //update the status bar
strcpy(szName, "dummy32");
- this->pSFParent->lpvtbl->fnGetFolderPath(this->pSFParent, szName + strlen(szName), sizeof(szName) - strlen(szName));
+ this->pSFParent->lpvtbl->fnGetFolderPath( this->pSFParent,
+ szName + strlen(szName),
+ sizeof(szName) - strlen(szName));
/* set the number of parts */
- this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS,
- SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult);
+ this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,
+ FCW_STATUS,
+ SB_SETPARTS,
+ 1,
+ (LPARAM)nPartArray,
+ &lResult);
/* set the text for the parts */
- this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS,
- SB_SETTEXT32A, 0, (LPARAM)szName, &lResult);
+ this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,
+ FCW_STATUS,
+ SB_SETTEXT32A,
+ 0,
+ (LPARAM)szName,
+ &lResult);
//add the docking window if necessary
if(g_bShowIDW)
{ ShellView_AddRemoveDockingWindow(this, TRUE);
- }
+ }
}
return S_OK;
}
static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
-{ TRACE(shell,"(%p) stub\n",this);
+{ TRACE(shell,"(%p)\n",this);
+
ListView_DeleteAllItems(this->hWndList);
ShellView_FillList(this);
+
return S_OK;
}
static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd)
-{ WNDCLASS32A wc;
- *phWnd = 0;
+{ WNDCLASS32A wc;
+ *phWnd = 0;
- TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
- TRACE(shell,"-- left=%i top=%i right=%i bottom=%i\n",prcView->left,prcView->top, prcView->right, prcView->bottom);
+ TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
+ TRACE(shell,"-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
+
+ /*set up the member variables*/
+ this->pShellBrowser = psb;
+ this->FolderSettings = *lpfs;
+
+ /*get our parent window*/
+ this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
+ this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));
+
+ /* try to get the ICommDlgBrowserInterface */
+ this->pCommDlgBrowser=NULL;
+ if ( SUCCEEDED (this->pShellBrowser->lpvtbl->fnQueryInterface( this->pShellBrowser,
+ &IID_ICommDlgBrowser,
+ (LPVOID*) &this->pCommDlgBrowser)))
+ { TRACE(shell,"-- CommDlgBrowser\n");
+ }
+
+ /*if our window class has not been registered, then do so*/
+ if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
+ { ZeroMemory(&wc, sizeof(wc));
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = (WNDPROC32) ShellView_WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = shell32_hInstance;
+ wc.hIcon = 0;
+ wc.hCursor = LoadCursor32A (0, IDC_ARROW32A);
+ wc.hbrBackground = (HBRUSH32) (COLOR_WINDOW + 1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = SV_CLASS_NAME;
-//if our window class has not been registered, then do so
- if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
- { ZeroMemory(&wc, sizeof(wc));
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC32) ShellView_WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = shell32_hInstance;
- wc.hIcon = 0;
- wc.hCursor = LoadCursor32A (0, IDC_ARROW32A);
- wc.hbrBackground = (HBRUSH32) (COLOR_WINDOW + 1);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = SV_CLASS_NAME;
-
- if(!RegisterClass32A(&wc))
- return E_FAIL;
- }
- //set up the member variables
- this->pShellBrowser = psb;
- this->FolderSettings = *lpfs;
+ if(!RegisterClass32A(&wc))
+ return E_FAIL;
+ }
- //get our parent window
- this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));
-
- *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
+ *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
- if(!*phWnd)
- return E_FAIL;
+ if(!*phWnd)
+ return E_FAIL;
- this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);
-
- return S_OK;
+ return S_OK;
}
static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
-{ TRACE(shell,"(%p) stub\n",this);
+{ TRACE(shell,"(%p)\n",this);
/*Make absolutely sure all our UI is cleaned up.*/
IShellView_UIActivate(this, SVUIA_DEACTIVATE);
@@ -1194,10 +1330,15 @@
return S_OK;
}
static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
-{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs);
-
- *lpfs = this->FolderSettings;
- return S_OK;
+{ TRACE(shell,"(%p)->(%p) vmode=%x flags=%x\n",this, lpfs,
+ this->FolderSettings.ViewMode, this->FolderSettings.fFlags);
+
+ if (lpfs)
+ { *lpfs = this->FolderSettings;
+ return NOERROR;
+ }
+ else
+ return E_INVALIDARG;
}
static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
{ FIXME(shell,"(%p) stub\n",this);
@@ -1211,11 +1352,11 @@
{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
return E_NOTIMPL;
}
-static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut)
+static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid, LPVOID *ppvOut)
{ char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
- FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut);
+ FIXME(shell,"(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)stub\n",this, uItem, xriid, ppvOut);
*ppvOut = NULL;
return E_NOTIMPL;
diff --git a/dlls/winaspi/Makefile.in b/dlls/winaspi/Makefile.in
new file mode 100644
index 0000000..eb83e44
--- /dev/null
+++ b/dlls/winaspi/Makefile.in
@@ -0,0 +1,15 @@
+DEFS = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = winaspi
+
+C_SRCS = \
+ winaspi16.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
diff --git a/dlls/winaspi/winaspi16.c b/dlls/winaspi/winaspi16.c
new file mode 100644
index 0000000..4a6c3fd
--- /dev/null
+++ b/dlls/winaspi/winaspi16.c
@@ -0,0 +1,492 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ldt.h>
+#include <memory.h>
+#include <unistd.h>
+#include <callback.h>
+#include "windows.h"
+#include "aspi.h"
+#include "winaspi.h"
+#include "options.h"
+#include "heap.h"
+#include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
+
+
+/* FIXME!
+ * 1) Residual byte length reporting not handled
+ * 2) Make this code re-entrant for multithreading
+ * 3) Only linux supported so far
+ */
+
+#ifdef linux
+static int
+ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
+{
+ int fd;
+ char idstr[20];
+ char device_str[50];
+ ASPI_DEVICE_INFO *curr;
+
+ /* search list of devices to see if we've opened it already.
+ * There is not an explicit open/close in ASPI land, so hopefully
+ * keeping a device open won't be a problem.
+ */
+
+ for (curr = ASPI_open_devices; curr; curr = curr->next) {
+ if (curr->hostId == prb->SRB_HaId &&
+ curr->target == prb->SRB_Target &&
+ curr->lun == prb->SRB_Lun) {
+ return curr->fd;
+ }
+ }
+
+ /* device wasn't cached, go ahead and open it */
+ sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
+
+ if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
+ TRACE(aspi, "Trying to open unlisted scsi device %s\n", idstr);
+ return -1;
+ }
+
+ TRACE(aspi, "Opening device %s=%s\n", idstr, device_str);
+
+ fd = open(device_str, O_RDWR);
+ if (fd == -1) {
+ int save_error = errno;
+ ERR(aspi, "Error opening device %s, errno=%d\n", device_str, save_error);
+ return -1;
+ }
+
+ /* device is now open */
+ curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
+ curr->fd = fd;
+ curr->hostId = prb->SRB_HaId;
+ curr->target = prb->SRB_Target;
+ curr->lun = prb->SRB_Lun;
+
+ /* insert new record at beginning of open device list */
+ curr->next = ASPI_open_devices;
+ ASPI_open_devices = curr;
+ return fd;
+}
+
+
+static void
+ASPI_DebugPrintCmd(SRB_ExecSCSICmd16 *prb, UINT16 mode)
+{
+ BYTE cmd;
+ int i;
+ BYTE *cdb;
+ BYTE *lpBuf = 0;
+ dbg_decl_str(aspi, 512);
+
+ switch (mode)
+ {
+ case ASPI_DOS:
+ /* translate real mode address */
+ if (prb->SRB_BufPointer)
+ lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+ break;
+ case ASPI_WIN16:
+ lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+ break;
+ }
+
+ switch (prb->CDBByte[0]) {
+ case CMD_INQUIRY:
+ TRACE(aspi, "{\n");
+ TRACE(aspi, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
+ TRACE(aspi, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
+ TRACE(aspi, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
+ TRACE(aspi, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
+ TRACE(aspi, "\tCONTROL: %d\n", prb->CDBByte[5]);
+ TRACE(aspi, "}\n");
+ break;
+ case CMD_SCAN_SCAN:
+ TRACE(aspi, "Transfer Length: %d\n", prb->CDBByte[4]);
+ break;
+ }
+
+ TRACE(aspi, "Host Adapter: %d\n", prb->SRB_HaId);
+ TRACE(aspi, "Flags: %d\n", prb->SRB_Flags);
+ if (TARGET_TO_HOST(prb)) {
+ TRACE(aspi, "\tData transfer: Target to host. Length checked.\n");
+ }
+ else if (HOST_TO_TARGET(prb)) {
+ TRACE(aspi, "\tData transfer: Host to target. Length checked.\n");
+ }
+ else if (NO_DATA_TRANSFERED(prb)) {
+ TRACE(aspi, "\tData transfer: none\n");
+ }
+ else {
+ WARN(aspi, "\tTransfer by scsi cmd. Length not checked\n");
+ }
+
+ TRACE(aspi, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
+ TRACE(aspi, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
+ TRACE(aspi, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
+ TRACE(aspi, "Target: %d\n", prb->SRB_Target);
+ TRACE(aspi, "Lun: %d\n", prb->SRB_Lun);
+ TRACE(aspi, "BufLen: %ld\n", prb->SRB_BufLen);
+ TRACE(aspi, "SenseLen: %d\n", prb->SRB_SenseLen);
+ TRACE(aspi, "BufPtr: %lx (%p)\n", prb->SRB_BufPointer, lpBuf);
+ TRACE(aspi, "LinkPointer %lx\n", prb->SRB_Rsvd1);
+ TRACE(aspi, "CDB Length: %d\n", prb->SRB_CDBLen);
+ TRACE(aspi, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
+ cdb = &prb->CDBByte[0];
+ cmd = prb->CDBByte[0];
+ for (i = 0; i < prb->SRB_CDBLen; i++) {
+ if (i != 0) dsprintf(aspi, ",");
+ dsprintf(aspi, "%02x", *cdb++);
+ }
+ TRACE(aspi, "CDB buffer[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_PrintSenseArea16(SRB_ExecSCSICmd16 *prb)
+{
+ int i;
+ BYTE *cdb;
+ dbg_decl_str(aspi, 512);
+
+ cdb = &prb->CDBByte[0];
+ for (i = 0; i < prb->SRB_SenseLen; i++) {
+ if (i) dsprintf(aspi, ",");
+ dsprintf(aspi, "%02x", *cdb++);
+ }
+ TRACE(aspi, "SenseArea[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_DebugPrintResult(SRB_ExecSCSICmd16 *prb, UINT16 mode)
+{
+ BYTE *lpBuf = 0;
+
+ switch (mode)
+ {
+ case ASPI_DOS:
+ /* translate real mode address */
+ if (prb->SRB_BufPointer)
+ lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+ break;
+ case ASPI_WIN16:
+ lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+ break;
+ }
+
+ switch (prb->CDBByte[0]) {
+ case CMD_INQUIRY:
+ TRACE(aspi, "Vendor: '%s'\n", lpBuf + INQUIRY_VENDOR);
+ break;
+ case CMD_TEST_UNIT_READY:
+ ASPI_PrintSenseArea16(prb);
+ break;
+ }
+}
+
+static WORD
+ASPI_ExecScsiCmd(DWORD ptrPRB, UINT16 mode)
+{
+ SRB_ExecSCSICmd16 *lpPRB = 0;
+ struct sg_header *sg_hd, *sg_reply_hdr;
+ int status;
+ BYTE *lpBuf = 0;
+ int in_len, out_len;
+ int error_code = 0;
+ int fd;
+
+ switch (mode)
+ {
+ case ASPI_DOS:
+ if (ptrPRB)
+ lpPRB = (SRB_ExecSCSICmd16 *)DOSMEM_MapRealToLinear(ptrPRB);
+ break;
+ case ASPI_WIN16:
+ lpPRB = PTR_SEG_TO_LIN(ptrPRB);
+ break;
+ }
+
+ ASPI_DebugPrintCmd(lpPRB, mode);
+
+ fd = ASPI_OpenDevice16(lpPRB);
+ if (fd == -1) {
+ ERR(aspi, "Failed: could not open device. Device permissions !?\n");
+ lpPRB->SRB_Status = SS_ERR;
+ return SS_ERR;
+ }
+
+ sg_hd = NULL;
+ sg_reply_hdr = NULL;
+
+ lpPRB->SRB_Status = SS_PENDING;
+
+ switch (mode)
+ {
+ case ASPI_DOS:
+ /* translate real mode address */
+ if (ptrPRB)
+ lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)lpPRB->SRB_BufPointer);
+ break;
+ case ASPI_WIN16:
+ lpBuf = PTR_SEG_TO_LIN(lpPRB->SRB_BufPointer);
+ break;
+ }
+
+ if (!lpPRB->SRB_CDBLen) {
+ WARN(aspi, "Failed: lpPRB->SRB_CDBLen = 0.\n");
+ lpPRB->SRB_Status = SS_ERR;
+ return SS_ERR;
+ }
+
+ /* build up sg_header + scsi cmd */
+ if (HOST_TO_TARGET(lpPRB)) {
+ /* send header, command, and then data */
+ in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen;
+ sg_hd = (struct sg_header *) malloc(in_len);
+ memset(sg_hd, 0, SCSI_OFF);
+ memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+ if (lpPRB->SRB_BufLen) {
+ memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpBuf, lpPRB->SRB_BufLen);
+ }
+ }
+ else {
+ /* send header and command - no data */
+ in_len = SCSI_OFF + lpPRB->SRB_CDBLen;
+ sg_hd = (struct sg_header *) malloc(in_len);
+ memset(sg_hd, 0, SCSI_OFF);
+ memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+ }
+
+ if (TARGET_TO_HOST(lpPRB)) {
+ out_len = SCSI_OFF + lpPRB->SRB_BufLen;
+ sg_reply_hdr = (struct sg_header *) malloc(out_len);
+ memset(sg_reply_hdr, 0, SCSI_OFF);
+ sg_hd->reply_len = out_len;
+ }
+ else {
+ out_len = SCSI_OFF;
+ sg_reply_hdr = (struct sg_header *) malloc(out_len);
+ memset(sg_reply_hdr, 0, SCSI_OFF);
+ sg_hd->reply_len = out_len;
+ }
+
+ status = write(fd, sg_hd, in_len);
+ if (status < 0 || status != in_len) {
+ int myerror = errno;
+
+ WARN(aspi, "Not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
+ if (status < 0) {
+ if (myerror == ENOMEM) {
+ MSG("ASPI: Linux generic scsi driver\n You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n Suggest 130560\n");
+ }
+ WARN(aspi, "errno: = %d\n", myerror);
+ }
+ goto error_exit;
+ }
+
+ status = read(fd, sg_reply_hdr, out_len);
+ if (status < 0 || status != out_len) {
+ WARN(aspi, "not enough bytes read from scsi device%d\n", status);
+ goto error_exit;
+ }
+
+ if (sg_reply_hdr->result != 0) {
+ error_code = sg_reply_hdr->result;
+ WARN(aspi, "reply header error (%d)\n", sg_reply_hdr->result);
+ goto error_exit;
+ }
+
+ if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) {
+ memcpy(lpBuf, sg_reply_hdr + 1, lpPRB->SRB_BufLen);
+ }
+
+ /* copy in sense buffer to amount that is available in client */
+ if (lpPRB->SRB_SenseLen) {
+ int sense_len = lpPRB->SRB_SenseLen;
+ if (lpPRB->SRB_SenseLen > 16)
+ sense_len = 16;
+ memcpy(SENSE_BUFFER(lpPRB), &sg_reply_hdr->sense_buffer[0], sense_len);
+ }
+
+
+ lpPRB->SRB_Status = SS_COMP;
+ lpPRB->SRB_HaStat = HASTAT_OK;
+ lpPRB->SRB_TargStat = STATUS_GOOD;
+
+ /* now do posting */
+
+ if (ASPI_POSTING(lpPRB) && lpPRB->SRB_PostProc) {
+ TRACE(aspi, "Post Routine (%lx) called\n", (DWORD) lpPRB->SRB_PostProc);
+ switch (mode)
+ {
+ case ASPI_DOS:
+ {
+ SEGPTR spPRB = MapLS(lpPRB);
+
+ Callbacks->CallASPIPostProc(lpPRB->SRB_PostProc, spPRB);
+ UnMapLS(spPRB);
+ break;
+ }
+ case ASPI_WIN16:
+ Callbacks->CallASPIPostProc(lpPRB->SRB_PostProc, ptrPRB);
+ break;
+ }
+ }
+
+ free(sg_reply_hdr);
+ free(sg_hd);
+ ASPI_DebugPrintResult(lpPRB, mode);
+ return SS_COMP;
+
+error_exit:
+ if (error_code == EBUSY) {
+ lpPRB->SRB_Status = SS_ASPI_IS_BUSY;
+ TRACE(aspi, "Device busy\n");
+ }
+ else {
+ WARN(aspi, "Failed\n");
+ lpPRB->SRB_Status = SS_ERR;
+ }
+
+ /* I'm not sure exactly error codes work here
+ * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ?
+ */
+ WARN(aspi, "error_exit\n");
+ free(sg_reply_hdr);
+ free(sg_hd);
+ return lpPRB->SRB_Status;
+}
+#endif
+
+
+/***********************************************************************
+ * GetASPISupportInfo16 (WINASPI.1)
+ */
+
+WORD WINAPI GetASPISupportInfo16()
+{
+#ifdef linux
+ TRACE(aspi, "GETASPISupportInfo16\n");
+ /* high byte SS_COMP - low byte number of host adapters.
+ * FIXME!!! The number of host adapters is incorrect.
+ * I'm not sure how to determine this under linux etc.
+ */
+ return ((SS_COMP << 8) | 1);
+#else
+ return ((SS_COMP << 8) | 0);
+#endif
+}
+
+
+DWORD ASPI_SendASPICommand(DWORD ptrSRB, UINT16 mode)
+{
+#ifdef linux
+ LPSRB16 lpSRB = 0;
+
+ switch (mode)
+ {
+ case ASPI_DOS:
+ if (ptrSRB)
+ lpSRB = (LPSRB16)DOSMEM_MapRealToLinear(ptrSRB);
+ break;
+ case ASPI_WIN16:
+ lpSRB = PTR_SEG_TO_LIN(ptrSRB);
+ break;
+ }
+
+ switch (lpSRB->common.SRB_Cmd) {
+ case SC_HA_INQUIRY:
+ lpSRB->inquiry.SRB_Status = SS_COMP; /* completed successfully */
+ if (lpSRB->inquiry.SRB_55AASignature == 0x55aa) {
+ TRACE(aspi, "Extended request detected (Adaptec's ASPIxDOS).\nWe don't support it at the moment.\n");
+ }
+ lpSRB->inquiry.SRB_ExtBufferSize = 0x2000; /* bogus value */
+ lpSRB->inquiry.HA_Count = 1; /* not always */
+ lpSRB->inquiry.HA_SCSI_ID = 7; /* not always ID 7 */
+ strcat(lpSRB->inquiry.HA_ManagerId, "Wine ASPI16"); /* max 15 chars */
+ strcat(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host
+adapter name */
+ memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */
+ lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */
+ FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId);
+ return SS_COMP;
+ case SC_GET_DEV_TYPE:
+ FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
+ break;
+ case SC_EXEC_SCSI_CMD:
+ return ASPI_ExecScsiCmd((DWORD)ptrSRB, mode);
+ break;
+ case SC_RESET_DEV:
+ FIXME(aspi, "Not implemented SC_RESET_DEV\n");
+ break;
+ default:
+ WARN(aspi, "Unknown command %d\n", lpSRB->common.SRB_Cmd);
+ }
+ return SS_INVALID_SRB;
+#else
+ return SS_INVALID_SRB;
+#endif
+}
+
+
+/***********************************************************************
+ * SendASPICommand16 (WINASPI.2)
+ */
+WORD WINAPI SendASPICommand16(SEGPTR segptr_srb)
+{
+#ifdef linux
+ return ASPI_SendASPICommand(segptr_srb, ASPI_WIN16);
+#else
+ return 0;
+#endif
+}
+
+
+/***********************************************************************
+ * GetASPIDLLVersion16 (WINASPI.4)
+ */
+
+DWORD WINAPI GetASPIDLLVersion16()
+{
+#ifdef linux
+ return (DWORD)2;
+#else
+ return (DWORD)0;
+#endif
+}
+
+
+void WINAPI ASPI_DOS_func(DWORD srb)
+{
+ ASPI_SendASPICommand(srb, ASPI_DOS);
+}
+
+
+/* returns a real mode call address to ASPI_DOS_func() */
+void ASPI_DOS_HandleInt(CONTEXT *context)
+{
+#ifdef linux
+ FARPROC16 DOS_func;
+ DWORD dos;
+ LPBYTE dosptr;
+
+ DOS_func = MODULE_GetWndProcEntry16("ASPI_DOS_func");
+ dos = GlobalDOSAlloc(5);
+ dosptr = (BYTE *)PTR_SEG_OFF_TO_LIN(LOWORD(dos), 0);
+ *dosptr++ = 0xea; /* ljmp */
+ *(FARPROC16 *)dosptr = DOS_func;
+
+ *(DWORD *)PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context))
+ = MAKELONG(0, HIWORD(dos)); /* real mode address */
+ RESET_CFLAG(context);
+ AX_reg(context) = CX_reg(context);
+#else
+ SET_CFLAG(context);
+#endif
+}
diff --git a/dlls/wnaspi32/Makefile.in b/dlls/wnaspi32/Makefile.in
new file mode 100644
index 0000000..1bf2b9b
--- /dev/null
+++ b/dlls/wnaspi32/Makefile.in
@@ -0,0 +1,15 @@
+DEFS = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = wnaspi32
+
+C_SRCS = \
+ winaspi32.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
diff --git a/dlls/wnaspi32/winaspi32.c b/dlls/wnaspi32/winaspi32.c
new file mode 100644
index 0000000..5447f8d
--- /dev/null
+++ b/dlls/wnaspi32/winaspi32.c
@@ -0,0 +1,373 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ldt.h>
+#include <memory.h>
+#include <unistd.h>
+#include <callback.h>
+#include "windows.h"
+#include "aspi.h"
+#include "wnaspi32.h"
+#include "options.h"
+#include "heap.h"
+#include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
+
+
+/* FIXME!
+ * 1) Residual byte length reporting not handled
+ * 2) Make this code re-entrant for multithreading
+ * 3) Only linux supported so far
+ */
+
+#ifdef linux
+static int
+ASPI_OpenDevice32(SRB_ExecSCSICmd32 *prb)
+{
+ int fd;
+ char idstr[20];
+ char device_str[50];
+ ASPI_DEVICE_INFO *curr;
+
+ /* search list of devices to see if we've opened it already.
+ * There is not an explicit open/close in ASPI land, so hopefully
+ * keeping a device open won't be a problem.
+ */
+
+ for (curr = ASPI_open_devices; curr; curr = curr->next) {
+ if (curr->hostId == prb->SRB_HaId &&
+ curr->target == prb->SRB_Target &&
+ curr->lun == prb->SRB_Lun) {
+ return curr->fd;
+ }
+ }
+
+ /* device wasn't cached, go ahead and open it */
+ sprintf(idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
+
+ if (!PROFILE_GetWineIniString(idstr, "Device", "", device_str, sizeof(device_str))) {
+ TRACE(aspi, "Trying to open unlisted scsi device %s\n", idstr);
+ return -1;
+ }
+
+ TRACE(aspi, "Opening device %s=%s\n", idstr, device_str);
+
+ fd = open(device_str, O_RDWR);
+ if (fd == -1) {
+ int save_error = errno;
+ ERR(aspi, "Error opening device %s, errno=%d\n", device_str, save_error);
+ return -1;
+ }
+
+ /* device is now open */
+ curr = HeapAlloc( SystemHeap, 0, sizeof(ASPI_DEVICE_INFO) );
+ curr->fd = fd;
+ curr->hostId = prb->SRB_HaId;
+ curr->target = prb->SRB_Target;
+ curr->lun = prb->SRB_Lun;
+
+ /* insert new record at beginning of open device list */
+ curr->next = ASPI_open_devices;
+ ASPI_open_devices = curr;
+ return fd;
+}
+
+
+static void
+ASPI_DebugPrintCmd32(SRB_ExecSCSICmd32 *prb)
+{
+ BYTE cmd;
+ int i;
+ BYTE *cdb;
+ dbg_decl_str(aspi, 512);
+
+ switch (prb->CDBByte[0]) {
+ case CMD_INQUIRY:
+ TRACE(aspi, "{\n");
+ TRACE(aspi, "\tEVPD: %d\n", prb->CDBByte[1] & 1);
+ TRACE(aspi, "\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
+ TRACE(aspi, "\tPAGE CODE: %d\n", prb->CDBByte[2]);
+ TRACE(aspi, "\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
+ TRACE(aspi, "\tCONTROL: %d\n", prb->CDBByte[5]);
+ TRACE(aspi, "}\n");
+ break;
+ case CMD_SCAN_SCAN:
+ TRACE(aspi, "Transfer Length: %d\n", prb->CDBByte[4]);
+ break;
+ }
+
+ TRACE(aspi, "Host Adapter: %d\n", prb->SRB_HaId);
+ TRACE(aspi, "Flags: %d\n", prb->SRB_Flags);
+ if (TARGET_TO_HOST(prb)) {
+ TRACE(aspi, "\tData transfer: Target to host. Length checked.\n");
+ }
+ else if (HOST_TO_TARGET(prb)) {
+ TRACE(aspi, "\tData transfer: Host to target. Length checked.\n");
+ }
+ else if (NO_DATA_TRANSFERED(prb)) {
+ TRACE(aspi, "\tData transfer: none\n");
+ }
+ else {
+ WARN(aspi, "\tTransfer by scsi cmd. Length not checked.\n");
+ }
+
+ TRACE(aspi, "\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
+ TRACE(aspi, "\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
+ TRACE(aspi, "\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
+ TRACE(aspi, "Target: %d\n", prb->SRB_Target);
+ TRACE(aspi, "Lun: %d\n", prb->SRB_Lun);
+ TRACE(aspi, "BufLen: %ld\n", prb->SRB_BufLen);
+ TRACE(aspi, "SenseLen: %d\n", prb->SRB_SenseLen);
+ TRACE(aspi, "BufPtr: %p\n", prb->SRB_BufPointer);
+ TRACE(aspi, "CDB Length: %d\n", prb->SRB_CDBLen);
+ TRACE(aspi, "POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
+ cdb = &prb->CDBByte[0];
+ cmd = prb->CDBByte[0];
+ for (i = 0; i < prb->SRB_CDBLen; i++) {
+ if (i != 0) dsprintf(aspi, ",");
+ dsprintf(aspi, "%02x", *cdb++);
+ }
+ TRACE(aspi, "CDB buffer[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_PrintSenseArea32(SRB_ExecSCSICmd32 *prb)
+{
+ int i;
+ BYTE *cdb;
+ dbg_decl_str(aspi, 512);
+
+ cdb = &prb->CDBByte[0];
+ for (i = 0; i < prb->SRB_SenseLen; i++) {
+ if (i) dsprintf(aspi, ",");
+ dsprintf(aspi, "%02x", *cdb++);
+ }
+ TRACE(aspi, "SenseArea[%s]\n", dbg_str(aspi));
+}
+
+static void
+ASPI_DebugPrintResult32(SRB_ExecSCSICmd32 *prb)
+{
+
+ switch (prb->CDBByte[0]) {
+ case CMD_INQUIRY:
+ TRACE(aspi, "Vendor: '%s'\n", prb->SRB_BufPointer + INQUIRY_VENDOR);
+ break;
+ case CMD_TEST_UNIT_READY:
+ ASPI_PrintSenseArea32(prb);
+ break;
+ }
+}
+
+static WORD
+ASPI_ExecScsiCmd32(SRB_ExecSCSICmd32 *lpPRB)
+{
+ struct sg_header *sg_hd, *sg_reply_hdr;
+ int status;
+ int in_len, out_len;
+ int error_code = 0;
+ int fd;
+
+ ASPI_DebugPrintCmd32(lpPRB);
+
+ fd = ASPI_OpenDevice32(lpPRB);
+ if (fd == -1) {
+ ERR(aspi, "Failed: could not open device. Device permissions !?\n");
+ lpPRB->SRB_Status = SS_ERR;
+ return SS_ERR;
+ }
+
+ sg_hd = NULL;
+ sg_reply_hdr = NULL;
+
+ lpPRB->SRB_Status = SS_PENDING;
+
+ if (!lpPRB->SRB_CDBLen) {
+ WARN(aspi, "Failed: lpPRB->SRB_CDBLen = 0.\n");
+ lpPRB->SRB_Status = SS_ERR;
+ return SS_ERR;
+ }
+
+ /* build up sg_header + scsi cmd */
+ if (HOST_TO_TARGET(lpPRB)) {
+ /* send header, command, and then data */
+ in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen;
+ sg_hd = (struct sg_header *) malloc(in_len);
+ memset(sg_hd, 0, SCSI_OFF);
+ memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+ if (lpPRB->SRB_BufLen) {
+ memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpPRB->SRB_BufPointer, lpPRB->SRB_BufLen);
+ }
+ }
+ else {
+ /* send header and command - no data */
+ in_len = SCSI_OFF + lpPRB->SRB_CDBLen;
+ sg_hd = (struct sg_header *) malloc(in_len);
+ memset(sg_hd, 0, SCSI_OFF);
+ memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
+ }
+
+ if (TARGET_TO_HOST(lpPRB)) {
+ out_len = SCSI_OFF + lpPRB->SRB_BufLen;
+ sg_reply_hdr = (struct sg_header *) malloc(out_len);
+ memset(sg_reply_hdr, 0, SCSI_OFF);
+ sg_hd->reply_len = out_len;
+ }
+ else {
+ out_len = SCSI_OFF;
+ sg_reply_hdr = (struct sg_header *) malloc(out_len);
+ memset(sg_reply_hdr, 0, SCSI_OFF);
+ sg_hd->reply_len = out_len;
+ }
+
+ status = write(fd, sg_hd, in_len);
+ if (status < 0 || status != in_len) {
+ int myerror = errno;
+
+ WARN(aspi, "Not enough bytes written to scsi device bytes=%d .. %d\n", in_len, status);
+ if (status < 0) {
+ if (myerror == ENOMEM) {
+ MSG("ASPI: Linux generic scsi driver\n You probably need to re-compile your kernel with a larger SG_BIG_BUFF value (sg.h)\n Suggest 130560\n");
+ }
+ WARN(aspi, "errno: = %d\n", myerror);
+ }
+ goto error_exit;
+ }
+
+ status = read(fd, sg_reply_hdr, out_len);
+ if (status < 0 || status != out_len) {
+ WARN(aspi, "not enough bytes read from scsi device%d\n", status);
+ goto error_exit;
+ }
+
+ if (sg_reply_hdr->result != 0) {
+ error_code = sg_reply_hdr->result;
+ WARN(aspi, "reply header error (%d)\n", sg_reply_hdr->result);
+ goto error_exit;
+ }
+
+ if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) {
+ memcpy(lpPRB->SRB_BufPointer, sg_reply_hdr + 1, lpPRB->SRB_BufLen);
+ }
+
+ /* copy in sense buffer to amount that is available in client */
+ if (lpPRB->SRB_SenseLen) {
+ int sense_len = lpPRB->SRB_SenseLen;
+ if (lpPRB->SRB_SenseLen > 16)
+ sense_len = 16;
+ memcpy(SENSE_BUFFER(lpPRB), &sg_reply_hdr->sense_buffer[0], sense_len);
+ }
+
+
+ lpPRB->SRB_Status = SS_COMP;
+ lpPRB->SRB_HaStat = HASTAT_OK;
+ lpPRB->SRB_TargStat = STATUS_GOOD;
+
+ /* now do posting */
+
+ if (lpPRB->SRB_PostProc) {
+ if (ASPI_POSTING(lpPRB)) {
+ TRACE(aspi, "Post Routine (%lx) called\n", (DWORD) lpPRB->SRB_PostProc);
+ (*lpPRB->SRB_PostProc)(lpPRB);
+ }
+ else
+ if (lpPRB->SRB_Flags & SRB_EVENT_NOTIFY) {
+ TRACE(aspi, "Setting event %04x\n", (HANDLE32)lpPRB->SRB_PostProc);
+ SetEvent((HANDLE32)lpPRB->SRB_PostProc); /* FIXME: correct ? */
+ }
+ }
+ free(sg_reply_hdr);
+ free(sg_hd);
+ ASPI_DebugPrintResult32(lpPRB);
+ return SS_COMP;
+
+error_exit:
+ if (error_code == EBUSY) {
+ lpPRB->SRB_Status = SS_ASPI_IS_BUSY;
+ TRACE(aspi, "Device busy\n");
+ }
+ else {
+ WARN(aspi, "Failed\n");
+ lpPRB->SRB_Status = SS_ERR;
+ }
+
+ /* I'm not sure exactly error codes work here
+ * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ?
+ */
+ WARN(aspi, "error_exit\n");
+ free(sg_reply_hdr);
+ free(sg_hd);
+ return lpPRB->SRB_Status;
+}
+#endif
+
+
+/*******************************************************************
+ * GetASPI32SupportInfo32 [WNASPI32.0]
+ *
+ * Checks if the ASPI subsystem is initialized correctly.
+ *
+ * RETURNS
+ * HIWORD: 0.
+ * HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT)
+ * LOBYTE of LOWORD: # of host adapters.
+ */
+DWORD WINAPI GetASPI32SupportInfo32()
+{
+ return ((SS_COMP << 8) | 1); /* FIXME: get # of host adapters installed */
+}
+
+
+/***********************************************************************
+ * SendASPI32Command32 (WNASPI32.1)
+ */
+DWORD WINAPI SendASPI32Command32(LPSRB32 lpSRB)
+{
+#ifdef linux
+ switch (lpSRB->common.SRB_Cmd) {
+ case SC_HA_INQUIRY:
+ lpSRB->inquiry.SRB_Status = SS_COMP; /* completed successfully */
+ lpSRB->inquiry.HA_Count = 1; /* not always */
+ lpSRB->inquiry.HA_SCSI_ID = 7; /* not always ID 7 */
+ strcat(lpSRB->inquiry.HA_ManagerId, "ASPI for WIN32"); /* max 15 chars, don't change */
+ strcat(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host adapter name */
+ memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */
+ lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */
+ FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId);
+ return SS_COMP;
+ case SC_GET_DEV_TYPE:
+ FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
+ break;
+ case SC_EXEC_SCSI_CMD:
+ return ASPI_ExecScsiCmd32(&lpSRB->cmd);
+ break;
+ case SC_RESET_DEV:
+ FIXME(aspi, "Not implemented SC_RESET_DEV\n");
+ break;
+ default:
+ WARN(aspi, "Unknown command %d\n", lpSRB->common.SRB_Cmd);
+ }
+ return SS_INVALID_SRB;
+#else
+ return SS_INVALID_SRB;
+#endif
+}
+
+
+/***********************************************************************
+ * GetASPI32DLLVersion32 (WNASPI32.3)
+ */
+
+DWORD WINAPI GetASPI32DLLVersion32()
+{
+#ifdef linux
+ return (DWORD)1;
+#else
+ return (DWORD)0;
+#endif
+}
+