Fixed DPA_LoadStream and improved DPA_Merge.
diff --git a/dlls/comctl32/comctl32undoc.c b/dlls/comctl32/comctl32undoc.c
index 45ac8c8..28847b8 100644
--- a/dlls/comctl32/comctl32undoc.c
+++ b/dlls/comctl32/comctl32undoc.c
@@ -19,6 +19,8 @@
#include <ctype.h>
#include "winbase.h"
+#include "winerror.h"
+#include "objbase.h"
#include "commctrl.h"
#include "debugtools.h"
@@ -37,6 +39,135 @@
extern LPWSTR WINAPI strstrw(LPCWSTR, LPCWSTR);
+typedef struct _STREAMDATA
+{
+ DWORD dwSize;
+ DWORD dwData2;
+ DWORD dwItems;
+} STREAMDATA, *PSTREAMDATA;
+
+typedef struct _LOADDATA
+{
+ INT nCount;
+ PVOID ptr;
+} LOADDATA, *LPLOADDATA;
+
+typedef HRESULT(CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
+
+
+/**************************************************************************
+ * DPA_LoadStream [COMCTL32.9]
+ *
+ * Loads a dynamic pointer array from a stream
+ *
+ * PARAMS
+ * phDpa [O] pointer to a handle to a dynamic pointer array
+ * loadProc [I] pointer to a callback function
+ * pStream [I] pointer to a stream
+ * lParam [I] application specific value
+ *
+ * NOTES
+ * No more information available yet!
+ */
+
+HRESULT WINAPI
+DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
+{
+ HRESULT errCode;
+ LARGE_INTEGER position;
+ ULARGE_INTEGER newPosition;
+ STREAMDATA streamData;
+ LOADDATA loadData;
+ ULONG ulRead;
+ HDPA hDpa;
+ PVOID *ptr;
+
+ FIXME ("phDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
+ phDpa, loadProc, pStream, lParam);
+
+ if (!phDpa || !loadProc || !pStream)
+ return E_INVALIDARG;
+
+ *phDpa = (HDPA)NULL;
+
+ position.LowPart = 0;
+ position.HighPart = 0;
+
+ errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &newPosition);
+ if (errCode != S_OK)
+ return errCode;
+
+ errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead);
+ if (errCode != S_OK)
+ return errCode;
+
+ FIXME ("dwSize=%lu dwData2=%lu dwItems=%lu\n",
+ streamData.dwSize, streamData.dwData2, streamData.dwItems);
+
+ if (lParam < sizeof(STREAMDATA) ||
+ streamData.dwSize < sizeof(STREAMDATA) ||
+ streamData.dwData2 < 1) {
+ errCode = E_FAIL;
+ }
+
+ /* create the dpa */
+ hDpa = DPA_Create (streamData.dwItems);
+ if (!hDpa)
+ return E_OUTOFMEMORY;
+
+ if (!DPA_Grow (hDpa, streamData.dwItems))
+ return E_OUTOFMEMORY;
+
+ /* load data from the stream into the dpa */
+ ptr = hDpa->ptrs;
+ for (loadData.nCount = 0; loadData.nCount < streamData.dwItems; loadData.nCount++) {
+ errCode = (loadProc)(&loadData, pStream, lParam);
+ if (errCode != S_OK) {
+ errCode = S_FALSE;
+ break;
+ }
+
+ *ptr = loadData.ptr;
+ ptr++;
+ }
+
+ /* set the number of items */
+ hDpa->nItemCount = loadData.nCount;
+
+ /* store the handle to the dpa */
+ *phDpa = hDpa;
+ FIXME ("new hDpa=%p\n", hDpa);
+
+ return errCode;
+}
+
+
+/**************************************************************************
+ * DPA_SaveStream [COMCTL32.10]
+ *
+ * Saves a dynamic pointer array to a stream
+ *
+ * PARAMS
+ * hDpa [I] handle to a dynamic pointer array
+ * loadProc [I] pointer to a callback function
+ * pStream [I] pointer to a stream
+ * lParam [I] application specific value
+ *
+ * NOTES
+ * No more information available yet!
+ */
+
+HRESULT WINAPI
+DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
+{
+
+ FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
+ hDpa, loadProc, pStream, lParam);
+
+ return E_FAIL;
+}
+
+
/**************************************************************************
* DPA_Merge [COMCTL32.11]
*
@@ -45,7 +176,7 @@
* hdpa2 [I] handle to a dynamic pointer array
* dwFlags [I] flags
* pfnSort [I] pointer to sort function
- * dwParam5 [I]
+ * pfnMerge [I] pointer to merge function
* lParam [I] application specific value
*
* NOTES
@@ -54,13 +185,15 @@
BOOL WINAPI
DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
- PFNDPACOMPARE pfnCompare, LPVOID pfnParam5, LPARAM lParam)
+ PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam)
{
- /* LPVOID *pWork1, *pWork2; */
- INT nCount1, nCount2;
+ LPVOID pWork1, pWork2;
+ INT nResult;
+ INT nCount, nIndex;
+ INT nNewItems;
- TRACE("(%p %p %08lx %p %p %08lx): stub!\n",
- hdpa1, hdpa2, dwFlags, pfnCompare, pfnParam5, lParam);
+ TRACE("(%p %p %08lx %p %p %08lx): semi stub!\n",
+ hdpa1, hdpa2, dwFlags, pfnCompare, pfnMerge, lParam);
if (IsBadWritePtr (hdpa1, sizeof(DPA)))
return FALSE;
@@ -71,45 +204,88 @@
if (IsBadCodePtr ((FARPROC)pfnCompare))
return FALSE;
- if (IsBadCodePtr ((FARPROC)pfnParam5))
+ if (IsBadCodePtr ((FARPROC)pfnMerge))
return FALSE;
if (dwFlags & DPAM_SORT) {
TRACE("sorting dpa's!\n");
+ if (hdpa1->nItemCount > 0)
DPA_Sort (hdpa1, pfnCompare, lParam);
+ TRACE ("dpa 1 sorted!\n");
+ if (hdpa2->nItemCount > 0)
DPA_Sort (hdpa2, pfnCompare, lParam);
+ TRACE ("dpa 2 sorted!\n");
}
- if (hdpa2->nItemCount <= 0)
+ if (hdpa2->nItemCount < 1)
return TRUE;
- nCount1 = hdpa1->nItemCount - 1;
+ TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n",
+ hdpa1->nItemCount, hdpa2->nItemCount);
- nCount2 = hdpa2->nItemCount - 1;
- FIXME("nCount1=%d nCount2=%d\n", nCount1, nCount2);
- FIXME("semi stub!\n");
+ /* preliminary hack - simply append the pointer list hdpa2 to hdpa1*/
+ for (nCount = 0; nCount < hdpa2->nItemCount; nCount++)
+ DPA_InsertPtr (hdpa1, hdpa1->nItemCount + 1, hdpa2->ptrs[nCount]);
+
#if 0
+ /* incomplete implementation */
- do {
+ pWork1 = &(hdpa1->ptrs[hdpa1->nItemCount - 1]);
+ pWork2 = &(hdpa2->ptrs[hdpa2->nItemCount - 1]);
+ nIndex = hdpa1->nItemCount - 1;
+ nCount = hdpa2->nItemCount - 1;
- if (nResult == 0) {
+ do
+ {
+ nResult = (pfnCompare)(pWork1, pWork2, lParam);
+ if (nResult == 0)
+ {
+ PVOID ptr;
+
+ ptr = (pfnMerge)(1, pWork1, pWork2, lParam);
+ if (!ptr)
+ return FALSE;
+
+ nCount--;
+ pWork2--;
+ pWork1 = ptr;
}
- else if (nResult > 0) {
+ else if (nResult < 0)
+ {
+ if (!dwFlags & 8)
+ {
+ PVOID ptr;
- }
- else {
+ ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1);
+ (pfnMerge)(2, ptr, NULL, lParam);
+ }
}
+ else
+ {
+ if (!dwFlags & 4)
+ {
+ PVOID ptr;
+
+ ptr = (pfnMerge)(3, pWork2, NULL, lParam);
+ if (!ptr)
+ return FALSE;
+ DPA_InsertPtr (hdpa1, nIndex, ptr);
+ }
+ nCount--;
+ pWork2--;
+ }
+
+ nIndex--;
+ pWork1--;
}
- while (nCount2 >= 0);
-
+ while (nCount >= 0);
#endif
-
return TRUE;
}
@@ -1875,31 +2051,3 @@
return (INT)(lpLoop-lpStr);
}
-
-/*************************************************************************
- * DPA_LoadStream [COMCTL32.9]
- *
- * NOTE: Ordinal is only accurate for Win98 / IE 4 and later
- */
-
-DWORD WINAPI DPA_LoadStream(HDPA *hDpa, DWORD pfnDpaLoadCallback, DWORD param3, DWORD param4)
-{
- FIXME("(%p %lx %lx %lx): partial stub!\n", hDpa, pfnDpaLoadCallback, param3, param4);
-
- *hDpa = DPA_Create(8);
-
- return(0);
-}
-
-/************************************************************************
- * DPA_SaveStream [COMCTL32.10]
- *
- * NOTE: Ordinal is only accurate for Win98 / IE 4 and later
- */
-
-DWORD WINAPI DPA_SaveStream(DWORD param1, DWORD param2, DWORD param3, DWORD param4)
-{
- FIXME("(%lx %lx %lx %lx): stub!\n", param1, param2, param3, param4);
-
- return(0);
-}
diff --git a/include/commctrl.h b/include/commctrl.h
index 9f546b2..4a33248 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -3054,7 +3054,8 @@
#define DPAM_SORT 0x0001
-BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, LPVOID, LPARAM);
+typedef PVOID(CALLBACK *PFNDPAMERGE)(DWORD,PVOID,PVOID,LPARAM);
+BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE, LPARAM);
typedef INT (CALLBACK *DPAENUMPROC)(LPVOID, DWORD);
VOID WINAPI DPA_EnumCallback (const HDPA, DPAENUMPROC, LPARAM);
diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec
index 14a0858..c78651a 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -14,8 +14,8 @@
6 stdcall CreateStatusWindowA(long str long long) CreateStatusWindowA
7 stdcall CreateToolbar(long long long long long long ptr long) CreateToolbar
8 stdcall CreateMappedBitmap(long long long ptr long) CreateMappedBitmap
- 9 stdcall DPA_LoadStream(ptr ptr long long) DPA_LoadStream
- 10 stdcall DPA_SaveStream(long long long long) DPA_SaveStream
+ 9 stdcall DPA_LoadStream(ptr ptr ptr long) DPA_LoadStream
+ 10 stdcall DPA_SaveStream(ptr ptr ptr long) DPA_SaveStream
11 stdcall DPA_Merge(ptr ptr long ptr ptr long) DPA_Merge
#12 stub Cctl1632_ThunkData32
13 stdcall MakeDragList(long) MakeDragList