Changeset 9370 for trunk/src/comctl32/commctrl.c
- Timestamp:
- Oct 29, 2002, 1:19:36 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/commctrl.c
r8382 r9370 1 /* 1 /* 2 2 * Common controls functions 3 3 * … … 18 18 * License along with this library; if not, write to the Free Software 19 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 * NOTES 22 * 23 * This code was audited for completeness against the documented features 24 * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair. 25 * 26 * Unless otherwise noted, we belive this code to be complete, as per 27 * the specification mentioned above. 28 * If you discover missing features, or bugs, please note them below. 29 * 30 * TODO 31 * -- implement GetMUILanguage + InitMUILanguage 32 * -- LibMain => DLLMain ("DLLMain takes over the functionality of both the 33 * LibMain and the WEP function.", MSDN) 34 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW 35 * -- FIXMEs + BUGS (search for them) 36 * 37 * Control Classes 38 * -- ICC_ANIMATE_CLASS 39 * -- ICC_BAR_CLASSES 40 * -- ICC_COOL_CLASSES 41 * -- ICC_DATE_CLASSES 42 * -- ICC_HOTKEY_CLASS 43 * -- ICC_INTERNET_CLASSES 44 * -- ICC_LINK_CLASS (not yet implemented) 45 * -- ICC_LISTVIEW_CLASSES 46 * -- ICC_NATIVEFNTCTL_CLASS 47 * -- ICC_PAGESCROLLER_CLASS 48 * -- ICC_PROGRESS_CLASS 49 * -- ICC_STANDARD_CLASSES (not yet implemented) 50 * -- ICC_TAB_CLASSES 51 * -- ICC_TREEVIEW_CLASSES 52 * -- ICC_UPDOWN_CLASS 53 * -- ICC_USEREX_CLASSES 54 * -- ICC_WIN95_CLASSES 20 55 */ 21 56 … … 108 143 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 109 144 { 110 TRACE("% x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);145 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved); 111 146 112 147 switch (fdwReason) { … … 116 151 /* create private heap */ 117 152 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0); 118 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);153 TRACE("Heap created: %p\n", COMCTL32_hHeap); 119 154 120 155 /* add global subclassing atom (used by 'tooltip' and 'updown') */ … … 181 216 /* destroy private heap */ 182 217 HeapDestroy (COMCTL32_hHeap); 183 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);218 TRACE("Heap destroyed: %p\n", COMCTL32_hHeap); 184 219 COMCTL32_hHeap = (HANDLE)NULL; 185 220 break; … … 219 254 VOID WINAPI 220 255 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu, 221 HINSTANCE hInst, HWND hwndStatus, LPUINTlpwIDs)256 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs) 222 257 { 223 258 UINT uMenuID = 0; … … 275 310 276 311 /*********************************************************************** 277 * ShowHideMenuCtl [COMCTL32.3] 312 * ShowHideMenuCtl [COMCTL32.3] 278 313 * 279 314 * Shows or hides controls and updates the corresponding menu item. … … 309 344 LPINT lpMenuId; 310 345 311 TRACE("% x, %x, %p\n", hwnd, uFlags, lpInfo);346 TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo); 312 347 313 348 if (lpInfo == NULL) … … 322 357 lpMenuId += 2; 323 358 324 if (GetMenuState ( lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {359 if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) { 325 360 /* uncheck menu item */ 326 CheckMenuItem ( lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);361 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED); 327 362 328 363 /* hide control */ … … 333 368 else { 334 369 /* check menu item */ 335 CheckMenuItem ( lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);370 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED); 336 371 337 372 /* show control */ … … 361 396 * 362 397 * lpInfo 363 * (will be written ...)398 * (will be written ...) 364 399 */ 365 400 … … 395 430 396 431 /*********************************************************************** 397 * DrawStatusTextW [COMCTL32. 28]432 * DrawStatusTextW [COMCTL32.@] 398 433 * 399 434 * Draws text with borders, like in a status bar. … … 439 474 r.left += 3; 440 475 if (style & SBT_RTLREADING) 441 FIXME("U supported RTL style!");476 FIXME("Unsupported RTL style!\n"); 442 477 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE); 443 478 SetBkMode(hdc, oldbkmode); … … 447 482 448 483 /*********************************************************************** 449 * DrawStatusText [COMCTL32. 27]484 * DrawStatusText [COMCTL32.@] 450 485 * DrawStatusTextA [COMCTL32.5] 451 486 * … … 479 514 480 515 /*********************************************************************** 481 * CreateStatusWindow [COMCTL32. 21]516 * CreateStatusWindow [COMCTL32.@] 482 517 * CreateStatusWindowA [COMCTL32.6] 483 518 * … … 498 533 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid) 499 534 { 500 return CreateWindowA(STATUSCLASSNAMEA, text, style, 535 return CreateWindowA(STATUSCLASSNAMEA, text, style, 501 536 CW_USEDEFAULT, CW_USEDEFAULT, 502 CW_USEDEFAULT, CW_USEDEFAULT, 503 parent, wid, 0, 0);504 } 505 506 507 /*********************************************************************** 508 * CreateStatusWindowW [COMCTL32. 22] Creates a status bar control537 CW_USEDEFAULT, CW_USEDEFAULT, 538 parent, (HMENU)wid, 0, 0); 539 } 540 541 542 /*********************************************************************** 543 * CreateStatusWindowW [COMCTL32.@] Creates a status bar control 509 544 * 510 545 * PARAMS … … 525 560 CW_USEDEFAULT, CW_USEDEFAULT, 526 561 CW_USEDEFAULT, CW_USEDEFAULT, 527 parent, wid, 0, 0);562 parent, (HMENU)wid, 0, 0); 528 563 } 529 564 … … 558 593 HWND hUD = 559 594 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy, 560 parent, id, inst, 0);595 parent, (HMENU)id, inst, 0); 561 596 if (hUD) { 562 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);597 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0); 563 598 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal)); 564 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0)); 599 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0)); 565 600 } 566 601 … … 593 628 594 629 /*********************************************************************** 595 * InitCommonControlsEx [COMCTL32. 84]630 * InitCommonControlsEx [COMCTL32.@] 596 631 * 597 632 * Registers the common controls. … … 607 642 * Only the additional common controls are registered by this function. 608 643 * The Win95 controls are registered at the DLL's initialization. 644 * 645 * FIXME 646 * implement the following control classes: 647 * ICC_LINK_CLASS 648 * ICC_STANDARD_CLASSES 609 649 */ 610 650 … … 676 716 677 717 /*********************************************************************** 678 * CreateToolbarEx [COMCTL32. 23] Creates a tool bar window718 * CreateToolbarEx [COMCTL32.@] Creates a tool bar window 679 719 * 680 720 * PARAMS … … 897 937 898 938 /*********************************************************************** 899 * DllGetVersion [COMCTL32. 25]939 * DllGetVersion [COMCTL32.@] 900 940 * 901 941 * Retrieves version information of the 'COMCTL32.DLL' … … 933 973 934 974 /*********************************************************************** 935 * DllInstall (COMCTL32. 26)975 * DllInstall (COMCTL32.@) 936 976 */ 937 977 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline) 938 978 { 939 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 979 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 940 980 debugstr_w(cmdline)); 941 981 … … 944 984 945 985 /*********************************************************************** 946 * _TrackMouseEvent [COMCTL32. 91]986 * _TrackMouseEvent [COMCTL32.@] 947 987 * 948 988 * Requests notification of mouse events … … 974 1014 975 1015 /************************************************************************* 976 * GetMUILanguage [COMCTL32.39] 977 * 978 * FIXME: What's this supposed to do? Apparently some i18n thing. 1016 * GetMUILanguage [COMCTL32.@] 1017 * 1018 * FIXME: "Returns the language currently in use by the common controls 1019 * for a particular process." (MSDN) 979 1020 * 980 1021 */ … … 986 1027 987 1028 /************************************************************************* 988 * InitMUILanguage [COMCTL32.85] 989 * 990 * FIXME: What's this supposed to do? Apparently some i18n thing. 1029 * InitMUILanguage [COMCTL32.@] 1030 * 1031 * FIXME: "Enables an application to specify a language to be used with 1032 * the common controls that is different than the system language." (MSDN) 991 1033 * 992 1034 */ … … 995 1037 { 996 1038 COMCTL32_uiLang = uiLang; 1039 } 1040 1041 1042 /*********************************************************************** 1043 * SetWindowSubclass [COMCTL32.@] 1044 * 1045 * Starts a window subclass 1046 * 1047 * PARAMS 1048 * hWnd [in] handle to window subclass. 1049 * pfnSubclass [in] Pointer to new window procedure. 1050 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass. 1051 * dwRef [in] Reference data to pass to window procedure. 1052 * 1053 * RETURNS 1054 * Success: non-zero 1055 * Failure: zero 1056 * 1057 * BUGS 1058 * If an application manually subclasses a window after subclassing it with 1059 * this API and then with this API again, then none of the previous 1060 * subclasses get called or the origional window procedure. 1061 */ 1062 1063 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass, 1064 UINT_PTR uIDSubclass, DWORD_PTR dwRef) 1065 { 1066 LPSUBCLASS_INFO stack; 1067 int newnum, n; 1068 1069 TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef); 1070 1071 /* Since the window procedure that we set here has two additional arguments, 1072 * we can't simply set it as the new window procedure of the window. So we 1073 * set our own window procedure and then calculate the other two arguments 1074 * from there. */ 1075 1076 /* See if we have been called for this window */ 1077 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass); 1078 if (!stack) { 1079 /* allocate stack */ 1080 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, 1081 sizeof(SUBCLASS_INFO)); 1082 if (!stack) { 1083 ERR ("Failed to allocate our Subclassing stack"); 1084 return FALSE; 1085 } 1086 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack); 1087 1088 /* set window procedure to our own and save the current one */ 1089 if (IsWindowUnicode (hWnd)) 1090 stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC, 1091 (LONG)DefSubclassProc); 1092 else 1093 stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC, 1094 (LONG)DefSubclassProc); 1095 } else { 1096 WNDPROC current; 1097 if (IsWindowUnicode (hWnd)) 1098 current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC); 1099 else 1100 current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC); 1101 1102 if (current != DefSubclassProc) { 1103 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n"); 1104 return FALSE; 1105 } 1106 } 1107 1108 /* Check to see if we have called this function with the same uIDSubClass 1109 * and pfnSubclass */ 1110 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++) 1111 if ((stack->SubclassProcs[n].id == uIDSubclass) && 1112 (stack->SubclassProcs[n].subproc == pfnSubclass)) { 1113 stack->SubclassProcs[n].ref = dwRef; 1114 return TRUE; 1115 } 1116 1117 if ((stack->stacknum + stack->stacknew) >= 32) { 1118 ERR ("We have a Subclass stack overflow, please increment size"); 1119 return FALSE; 1120 } 1121 1122 /* we can't simply increment both stackpos and stacknum because there might 1123 * be a window procedure running lower in the stack, we can only get them 1124 * up to date once the last window procedure has run */ 1125 if (stack->stacknum == stack->stackpos) { 1126 stack->stacknum++; 1127 stack->stackpos++; 1128 } else 1129 stack->stacknew++; 1130 1131 newnum = stack->stacknew + stack->stacknum - 1; 1132 1133 stack->SubclassProcs[newnum].subproc = pfnSubclass; 1134 stack->SubclassProcs[newnum].ref = dwRef; 1135 stack->SubclassProcs[newnum].id = uIDSubclass; 1136 1137 return TRUE; 1138 } 1139 1140 1141 /*********************************************************************** 1142 * GetWindowSubclass [COMCTL32.@] 1143 * 1144 * Gets the Reference data from a subclass. 1145 * 1146 * PARAMS 1147 * hWnd [in] Handle to window which were subclassing 1148 * pfnSubclass [in] Pointer to the subclass procedure 1149 * iID [in] Unique indentifier of the subclassing procedure 1150 * pdwRef [out] Pointer to the reference data 1151 * 1152 * RETURNS 1153 * Success: non-sero 1154 * Failure: zero 1155 */ 1156 1157 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass, 1158 UINT_PTR uID, DWORD_PTR *pdwRef) 1159 { 1160 LPSUBCLASS_INFO stack; 1161 int n; 1162 1163 TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef); 1164 1165 /* See if we have been called for this window */ 1166 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass); 1167 if (!stack) 1168 return FALSE; 1169 1170 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++) 1171 if ((stack->SubclassProcs[n].id == uID) && 1172 (stack->SubclassProcs[n].subproc == pfnSubclass)) { 1173 *pdwRef = stack->SubclassProcs[n].ref; 1174 return TRUE; 1175 } 1176 1177 return FALSE; 1178 } 1179 1180 1181 /*********************************************************************** 1182 * RemoveWindowSubclass [COMCTL32.@] 1183 * 1184 * Removes a window subclass. 1185 * 1186 * PARAMS 1187 * hWnd [in] Handle to the window were subclassing 1188 * pfnSubclass [in] Pointer to the subclass procedure 1189 * uID [in] Unique identifier of this subclass 1190 * 1191 * RETURNS 1192 * Success: non-zero 1193 * Failure: zero 1194 */ 1195 1196 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID) 1197 { 1198 LPSUBCLASS_INFO stack; 1199 int n; 1200 1201 TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID); 1202 1203 /* Find the Subclass to remove */ 1204 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass); 1205 if (!stack) 1206 return FALSE; 1207 1208 if ((stack->stacknum == stack->stackpos == 1) && !stack->stacknew) { 1209 TRACE("Last Subclass removed, cleaning up\n"); 1210 /* clean up our heap and reset the origional window procedure */ 1211 if (IsWindowUnicode (hWnd)) 1212 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc); 1213 else 1214 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc); 1215 HeapFree (GetProcessHeap (), 0, stack); 1216 RemovePropA( hWnd, COMCTL32_aSubclass ); 1217 return TRUE; 1218 } 1219 1220 for (n = stack->stacknum + stack->stacknew - 1; n >= 0; n--) 1221 if ((stack->SubclassProcs[n].id == uID) && 1222 (stack->SubclassProcs[n].subproc == pfnSubclass)) { 1223 if (n != (stack->stacknum + stack->stacknew)) 1224 /* Fill the hole in the stack */ 1225 memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1], 1226 sizeof(stack->SubclassProcs[0]) * (stack->stacknew + stack->stacknum - n)); 1227 stack->SubclassProcs[n].subproc = NULL; 1228 stack->SubclassProcs[n].ref = 0; 1229 stack->SubclassProcs[n].id = 0; 1230 1231 /* If we are currently running a window procedure we have to manipulate 1232 * the stack position pointers so that we don't corrupt the stack */ 1233 if ((n < stack->stackpos) || (stack->stackpos == stack->stacknum)) { 1234 stack->stacknum--; 1235 stack->stackpos--; 1236 } else if (n >= stack->stackpos) 1237 stack->stacknew--; 1238 return TRUE; 1239 } 1240 1241 return FALSE; 1242 } 1243 1244 1245 /*********************************************************************** 1246 * DefSubclassProc [COMCTL32.@] 1247 * 1248 * Calls the next window procedure (ie. the one before this subclass) 1249 * 1250 * PARAMS 1251 * hWnd [in] The window that we're subclassing 1252 * uMsg [in] Message 1253 * wParam [in] WPARAM 1254 * lParam [in] LPARAM 1255 * 1256 * RETURNS 1257 * Success: non-zero 1258 * Failure: zero 1259 */ 1260 1261 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1262 { 1263 LPSUBCLASS_INFO stack; 1264 int stackpos; 1265 LRESULT ret; 1266 1267 /* retrieve our little stack from the Properties */ 1268 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass); 1269 if (!stack) { 1270 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd); 1271 return 0; 1272 } 1273 1274 /* If we are at pos 0 then we have to call the origional window procedure */ 1275 if (stack->stackpos == 0) { 1276 if (IsWindowUnicode (hWnd)) 1277 return CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam); 1278 else 1279 return CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam); 1280 } 1281 1282 stackpos = --stack->stackpos; 1283 /* call the Subclass procedure from the stack */ 1284 ret = stack->SubclassProcs[stackpos].subproc (hWnd, uMsg, wParam, lParam, 1285 stack->SubclassProcs[stackpos].id, stack->SubclassProcs[stackpos].ref); 1286 stack->stackpos++; 1287 1288 if ((stack->stackpos == stack->stacknum) && stack->stacknew) { 1289 stack->stacknum += stack->stacknew; 1290 stack->stackpos += stack->stacknew; 1291 stack->stacknew = 0; 1292 } 1293 1294 /* If we removed the last entry in our stack while a window procedure was 1295 * running then we have to clean up */ 1296 if (stack->stackpos == stack->stacknum == 0) { 1297 TRACE("Last Subclass removed, cleaning up\n"); 1298 /* clean up our heap and reset the origional window procedure */ 1299 if (IsWindowUnicode (hWnd)) 1300 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc); 1301 else 1302 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc); 1303 HeapFree (GetProcessHeap (), 0, stack); 1304 RemovePropA( hWnd, COMCTL32_aSubclass ); 1305 return TRUE; 1306 } 1307 1308 return ret; 997 1309 } 998 1310 … … 1011 1323 * Failure: NULL 1012 1324 */ 1325 1013 1326 HWND 1014 1327 COMCTL32_CreateToolTip(HWND hwndOwner) … … 1053 1366 * none 1054 1367 */ 1368 1055 1369 VOID 1056 1370 COMCTL32_RefreshSysColors(void)
Note:
See TracChangeset
for help on using the changeset viewer.