Release 960324
[wine] / windows / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <string.h>
8 #include "win.h"
9 #include "user.h"
10 #include "callback.h"
11 #include "stddebug.h"
12 /* #define DEBUG_PROP */
13 #include "debug.h"
14
15
16 typedef struct
17 {
18     HANDLE next;       /* Next property in window list */
19     ATOM   atom;       /* Atom (or 0 if string) */
20     HANDLE hData;      /* User's data */
21     char   string[1];  /* Property string */
22 } PROPERTY;
23
24
25 /***********************************************************************
26  *           SetProp   (USER.26)
27  */
28 BOOL SetProp( HWND hwnd, SEGPTR str, HANDLE hData )
29 {
30     HANDLE hProp;
31     PROPERTY *prop;
32     WND *wndPtr;
33
34     dprintf_prop( stddeb, "SetProp: %04x %08lx %04x\n",
35                   hwnd, (DWORD)str, hData );
36     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
37     hProp = USER_HEAP_ALLOC( sizeof(PROPERTY) + 
38                              (HIWORD(str) ? strlen(PTR_SEG_TO_LIN(str)) : 0 ));
39     if (!hProp) return FALSE;
40     prop = (PROPERTY *) USER_HEAP_LIN_ADDR( hProp );
41     if (HIWORD(str))  /* string */
42     {
43         prop->atom = 0;
44         strcpy( prop->string, PTR_SEG_TO_LIN(str) );
45     }
46     else  /* atom */
47     {
48         prop->atom = LOWORD(str);
49         prop->string[0] = '\0';
50     }
51     prop->hData = hData;
52     prop->next = wndPtr->hProp;
53     wndPtr->hProp = hProp;
54     return TRUE;
55 }
56
57
58 /***********************************************************************
59  *           GetProp   (USER.25)
60  */
61 HANDLE GetProp( HWND hwnd, SEGPTR str )
62 {
63     HANDLE hProp;
64     WND *wndPtr;
65
66     dprintf_prop( stddeb, "GetProp: %04x %08lx\n", hwnd, (DWORD)str );
67     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
68     hProp = wndPtr->hProp;
69     while (hProp)
70     {
71         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
72         if (HIWORD(str))
73         {
74             if (!prop->atom && !lstrcmpi( prop->string, PTR_SEG_TO_LIN(str)))
75                 return prop->hData;
76         }
77         else if (prop->atom && (prop->atom == LOWORD(str))) return prop->hData;
78         hProp = prop->next;
79     }
80     return 0;
81 }
82
83
84 /***********************************************************************
85  *           RemoveProp   (USER.24)
86  */
87 HANDLE RemoveProp( HWND hwnd, SEGPTR str )
88 {
89     HANDLE *hProp;
90     WND *wndPtr;
91
92     dprintf_prop( stddeb, "RemoveProp: %04x %08lx\n", hwnd, (DWORD)str );
93     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
94     hProp = &wndPtr->hProp;
95     while (*hProp)
96     {
97         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR( *hProp );
98         if ((HIWORD(str) && !prop->atom &&
99              !lstrcmpi( prop->string, PTR_SEG_TO_LIN(str))) ||
100             (!HIWORD(str) && prop->atom && (prop->atom == LOWORD(str))))
101         {
102             HANDLE hNext = prop->next;
103             HANDLE hData = prop->hData;
104             USER_HEAP_FREE( *hProp );
105             *hProp = hNext;
106             return hData;
107         }
108         hProp = &prop->next;
109     }
110     return 0;
111 }
112
113
114 /***********************************************************************
115  *           EnumProps   (USER.27)
116  */
117 INT EnumProps( HWND hwnd, PROPENUMPROC func )
118 {
119     int ret = -1;
120     HANDLE hProp;
121     WND *wndPtr;
122
123     dprintf_prop( stddeb, "EnumProps: %04x %08lx\n", hwnd, (LONG)func );
124     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
125     hProp = wndPtr->hProp;
126     while (hProp)
127     {
128         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
129         
130         dprintf_prop( stddeb, "  Callback: atom=%04x data=%04x str='%s'\n",
131                       prop->atom, prop->hData, prop->string );
132
133           /* Already get the next in case the callback */
134           /* function removes the current property.    */
135         hProp = prop->next;
136         ret = CallEnumPropProc( func, hwnd,
137                                 prop->atom ? 
138                                   (LONG)MAKELONG( prop->atom, 0 )
139                                 :
140                                   (LONG)(USER_HEAP_SEG_ADDR(hProp) +
141                                          ((int)prop->string - (int)prop)),
142                                 prop->hData );
143         if (!ret) break;
144     }
145     return ret;
146 }