Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

922 lines
29 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WUCLASS.C
  8. * WOW32 16-bit User API support
  9. *
  10. * History:
  11. * Created 07-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wuclass.c);
  16. extern HANDLE ghInstanceUser32;
  17. extern WORD gUser16hInstance;
  18. /*++
  19. BOOL GetClassInfo(<hInstance>, <lpClassName>, <lpWndClass>)
  20. HANDLE <hInstance>;
  21. LPSTR <lpClassName>;
  22. LPWNDCLASS <lpWndClass>;
  23. The %GetClassInfo% function retrieves information about a window class. The
  24. <hInstance> parameter identifies the instance of the application that
  25. created the class, and the <lpClassName> parameter identifies the window
  26. class. If the function locates the specified window class, it copies the
  27. %WNDCLASS% data used to register the window class to the %WNDCLASS%
  28. structure pointed to by the <lpWndClass> parameter.
  29. <hInstance>
  30. Identifies the instance of the application that created the class. To
  31. retrieve information on classes defined by Windows (such as buttons or
  32. list boxes), set hInstance to NULL.
  33. <lpClassName>
  34. Points to a null-terminated string that contains the name of the
  35. class to find. If the high-order word of this parameter is NULL, the
  36. low-order word is assumed to be a value returned by the
  37. %MAKEINTRESOURCE% macro used when the class was created.
  38. <lpWndClass>
  39. Points to the %WNDCLASS% structure that will receive the class
  40. information.
  41. The return value is TRUE if the function found a matching class and
  42. successfully copied the data; the return value is FALSE if the function did
  43. not find a matching class.
  44. The %lpszClassName%, %lpszMenuName%, and %hInstance% members of the
  45. %WNDCLASS% structure are <not> set by this function. The menu name is
  46. not stored internally and cannot be returned. The class name is already
  47. known since it is passed to this function. The %GetClassInfo% function
  48. returns all other fields with the values used when the class was
  49. registered.
  50. --*/
  51. ULONG FASTCALL WU32GetClassInfo(PVDMFRAME pFrame)
  52. {
  53. ULONG ul;
  54. PSZ psz2, pszClass;
  55. WNDCLASS t3;
  56. register PGETCLASSINFO16 parg16;
  57. WORD w;
  58. HINSTANCE hInst;
  59. PWC pwc = NULL;
  60. PWNDCLASS16 pwc16;
  61. CHAR szAtomName[WOWCLASS_ATOM_NAME];
  62. GETARGPTR(pFrame, sizeof(GETCLASSINFO16), parg16);
  63. GETPSZIDPTR(parg16->f2, psz2);
  64. if ( HIWORD(psz2) == 0 ) {
  65. pszClass = szAtomName;
  66. GetAtomName( (ATOM)psz2, pszClass, WOWCLASS_ATOM_NAME );
  67. } else {
  68. pszClass = psz2;
  69. }
  70. // map hInst user16 to hMod user32
  71. if(parg16->f1 == gUser16hInstance) {
  72. hInst = ghInstanceUser32;
  73. }
  74. else {
  75. hInst = HMODINST32(parg16->f1);
  76. }
  77. ul = GETBOOL16(GetClassInfo(hInst, pszClass, &t3));
  78. // This fine piece of hackery mimicks the difference between the class list
  79. // search algorithms in Win3.1 & SUR. Essentially SUR checks the private,
  80. // public, and global class lists while Win3.1 only checks the private and
  81. // global lists. Note we are striving for Win3.1 compatibility here -- not
  82. // always the logical thing! Finding an existing *stale* class breaks some
  83. // apps! Bug #31269 a-craigj, GerardoB
  84. // Restrict this hack to PageMaker 50a for now
  85. if(CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_FAKECLASSINFOFAIL) {
  86. if(ul && hInst) {
  87. // if this class wasn't registered by this app, AND it's not a global
  88. // class, then it must have come from the public list and this app
  89. // wouldn't know about it on Win3.1 -- so lie and say it doesn't exist!
  90. // Note: The high word is the *hModule* which is what Win3.1 AND NT save
  91. // with the class internally (not the hInstance!)
  92. if((HIWORD(t3.hInstance) != HIWORD(hInst)) && !(t3.style & CS_GLOBALCLASS)) {
  93. WOW32WARNMSGF(0,("\nWOW:GetClassInfo force failure hack:\n class = '%s' wc.hInstance = %X app_hInst = %X\n\n", pszClass, t3.hInstance, hInst));
  94. ul = 0;
  95. }
  96. }
  97. }
  98. if (ul) {
  99. //
  100. // If the class is a 'standard' class, replace the class proc
  101. // with a thunk proc
  102. //
  103. GETVDMPTR(parg16->f3, sizeof(WNDCLASS16), pwc16);
  104. STOREWORD(pwc16->style, t3.style);
  105. if (!WOW32_stricmp(pszClass, "edit")) {
  106. STOREWORD(pwc16->style, (FETCHWORD(pwc16->style) & ~CS_GLOBALCLASS));
  107. }
  108. STOREDWORD(pwc16->vpfnWndProc, 0);
  109. // if this class was registered by WOW
  110. if (IsWOWProc (t3.lpfnWndProc)) {
  111. //Unmark the proc and restore the high bits from rpl field
  112. UnMarkWOWProc (t3.lpfnWndProc,pwc16->vpfnWndProc);
  113. STORESHORT(pwc16->cbClsExtra, t3.cbClsExtra );
  114. } else {
  115. pwc16->vpfnWndProc = GetThunkWindowProc((DWORD)t3.lpfnWndProc, pszClass, NULL, NULL);
  116. STORESHORT(pwc16->cbClsExtra, t3.cbClsExtra);
  117. }
  118. #ifdef OLD_WAY
  119. if (parg16->f1 ||
  120. !(pwc16->vpfnWndProc = GetThunkWindowProc((DWORD)t3.lpfnWndProc, pszClass, NULL, NULL))) {
  121. pwc = FindClass16(pszClass, (HINST16)parg16->f1);
  122. STOREDWORD(pwc16->vpfnWndProc, pwc->vpfnWndProc);
  123. }
  124. #endif
  125. STORESHORT(pwc16->cbWndExtra, t3.cbWndExtra);
  126. // Win3.1 copies the hInst passed in by the app into the WNDCLASS struct
  127. // unless hInst == NULL, in which case they copy user's hInst
  128. if((!parg16->f1) || (t3.hInstance == ghInstanceUser32)) {
  129. w = gUser16hInstance;
  130. } else {
  131. w = VALIDHMOD(t3.hInstance);
  132. if(w != BOGUSGDT) {
  133. w = parg16->f1;
  134. }
  135. }
  136. STOREWORD(pwc16->hInstance, w);
  137. w = GETHICON16(t3.hIcon); STOREWORD(pwc16->hIcon, w);
  138. w = GETHCURSOR16(t3.hCursor); STOREWORD(pwc16->hCursor, w);
  139. w = ((ULONG)t3.hbrBackground > COLOR_ENDCOLORS) ?
  140. GETHBRUSH16(t3.hbrBackground) : (WORD)t3.hbrBackground;
  141. STOREWORD(pwc16->hbrBackground, w);
  142. // These are strange assignments. We don't keep the class name or
  143. // menu name in 16-bit memory. For class name, USER32 just returns
  144. // the value which is passed as the second parameter, which works
  145. // MOST of the time; we do the same. For the menu name, USER32 just
  146. // returns the value which was passed when the class was registered.
  147. // There are some situations where these psz's might go out of scope
  148. // and no longer be valid when the application attempts to use them.
  149. // IF YOU EVER FIND AN APPLICATION WHICH GETS THE WRONG
  150. // THING AND IT FAILS BECAUSE OF IT, SOME NASTY HACKING WILL HAVE
  151. // TO BE DONE AND IT SHOULD BE DONE IN USER32 ALSO...
  152. // -BobDay
  153. //
  154. if ( pwc = FindClass16(pszClass, (HINST16)parg16->f1)) {
  155. STOREDWORD(pwc16->vpszMenuName, pwc->vpszMenu);
  156. } else {
  157. STOREDWORD(pwc16->vpszMenuName, 0 );
  158. }
  159. STOREDWORD(pwc16->vpszClassName, parg16->f2);
  160. FLUSHVDMPTR(parg16->f3, sizeof(WNDCLASS16), pwc16);
  161. FREEVDMPTR(pwc16);
  162. }
  163. FREEPSZIDPTR(psz2);
  164. FREEARGPTR(parg16);
  165. RETURN(ul);
  166. }
  167. /*++
  168. LONG GetClassLong(<hwnd>, <nIndex>)
  169. HWND <hwnd>;
  170. int <nIndex>;
  171. The %GetClassLong% function retrieves the long value specified by the
  172. <nIndex> parameter from the %WNDCLASS% structure of the window specified by
  173. the <hwnd> parameter.
  174. <hwnd>
  175. Identifies the window.
  176. <nIndex>
  177. Specifies the byte offset of the value to be retrieved. It can also
  178. be the following value:
  179. GCL_WNDPROC
  180. Retrieves a long pointer to the window function.
  181. GCL_MENUNAME
  182. Retrieves a long pointer to the menu name.
  183. The return value specifies the value retrieved from the %WNDCLASS%
  184. structure.
  185. To access any extra four-byte values allocated when the window-class
  186. structure was created, use a positive byte offset as the index specified by
  187. the <nIndex> parameter. The first four-byte value in the extra space is at
  188. offset zero, the next four-byte value is at offset 4, and so on.
  189. --*/
  190. ULONG FASTCALL WU32GetClassLong(PVDMFRAME pFrame)
  191. {
  192. ULONG ul;
  193. INT iOffset;
  194. HWND hwnd;
  195. register PWW pww;
  196. register PWC pwc;
  197. register PGETCLASSLONG16 parg16;
  198. GETARGPTR(pFrame, sizeof(GETCLASSLONG16), parg16);
  199. // Make sure Win32 didn't change offsets for GCL constants
  200. #if (GCL_WNDPROC != (-24) || GCL_MENUNAME != (-8))
  201. #error Win16/Win32 GCL constants differ
  202. #endif
  203. // Make sure the 16-bit app is requesting allowable offsets
  204. iOffset = INT32(parg16->f2);
  205. WOW32ASSERT(iOffset >= 0 ||
  206. iOffset == GCL_WNDPROC ||
  207. iOffset == GCL_MENUNAME);
  208. hwnd = HWND32(parg16->f1);
  209. switch (iOffset) {
  210. case GCL_WNDPROC:
  211. {
  212. DWORD dwProc32;
  213. dwProc32 = GetClassLong(hwnd, iOffset);
  214. if ( IsWOWProc (dwProc32)) {
  215. if ( HIWORD(dwProc32) == WNDPROC_HANDLE ) {
  216. //
  217. // Class has a window proc which is really a handle
  218. // to a proc. This happens when there is some
  219. // unicode to ansi transition or vice versa.
  220. //
  221. pww = FindPWW( hwnd);
  222. if ( pww == NULL ) {
  223. ul = 0;
  224. } else {
  225. ul = GetThunkWindowProc(dwProc32,NULL,pww,hwnd);
  226. }
  227. } else {
  228. //
  229. // Class already has a 16:16 address
  230. //
  231. //Unmark the proc and restore the high bits from rpl field
  232. UnMarkWOWProc (dwProc32,ul);
  233. }
  234. } else {
  235. //
  236. // Class has a 32-bit proc, return an allocated thunk
  237. //
  238. pww = FindPWW(hwnd);
  239. if ( pww == NULL ) {
  240. ul = 0;
  241. } else {
  242. ul = GetThunkWindowProc(dwProc32,NULL,pww,hwnd);
  243. }
  244. }
  245. }
  246. break;
  247. case GCL_MENUNAME:
  248. if (pwc = FindPWC(hwnd)) {
  249. ul = pwc->vpszMenu;
  250. } else {
  251. ul = 0;
  252. }
  253. break;
  254. case GCL_CBCLSEXTRA:
  255. ul = GetClassLong(hwnd, GCL_CBCLSEXTRA);
  256. break;
  257. default:
  258. ul = GetClassLong(hwnd, iOffset);
  259. break;
  260. }
  261. FREEARGPTR(parg16);
  262. RETURN(ul);
  263. }
  264. /*++
  265. WORD GetClassWord(<hwnd>, <nIndex>)
  266. HWND <hwnd>;
  267. int <nIndex>;
  268. The %GetClassWord% function retrieves the word that is specified by the
  269. <nIndex> parameter from the %WNDCLASS% structure of the window specified by
  270. the <hwnd> parameter.
  271. <hwnd>
  272. Identifies the window.
  273. <nIndex>
  274. Specifies the byte offset of the value to be retrieved. It can also
  275. be one of the following values:
  276. GCL_CBCLSEXTRA
  277. Tells how many bytes of additional class information you have. For
  278. information on how to access this memory, see the following "Comments"
  279. section.
  280. GCL_CBWNDEXTRA
  281. Tells how many bytes of additional window information you have. For
  282. information on how to access this memory, see the following<>Comments
  283. section.
  284. GCL_HBRBACKGROUND
  285. Retrieves a handle to the background brush.
  286. GCL_HCURSOR
  287. Retrieves a handle to the cursor.
  288. GCL_HICON
  289. Retrieves a handle to the icon.
  290. GCL_HMODULE
  291. Retrieves a handle to the module.
  292. GCL_STYLE
  293. Retrieves the window-class style bits.
  294. The return value specifies the value retrieved from the %WNDCLASS%
  295. structure.
  296. To access any extra two-byte values allocated when the window-class
  297. structure was created, use a positive byte offset as the index specified by
  298. the <nIndex> parameter, starting at zero for the first two-byte value in the
  299. extra space, 2 for the next two-byte value and so on.
  300. --*/
  301. ULONG FASTCALL WU32GetClassWord(PVDMFRAME pFrame)
  302. {
  303. ULONG ul;
  304. HWND hwnd;
  305. INT iOffset;
  306. register PGETCLASSWORD16 parg16;
  307. GETARGPTR(pFrame, sizeof(GETCLASSWORD16), parg16);
  308. // Make sure Win32 didn't change offsets
  309. #if (GCL_HBRBACKGROUND != (-10) || GCL_HCURSOR != (-12) || GCL_HICON != (-14) || GCL_HMODULE != (-16) || GCL_CBWNDEXTRA != (-18) || GCL_CBCLSEXTRA != (-20) || GCL_STYLE != (-26))
  310. #error Win16/Win32 class-word constants differ
  311. #endif
  312. // Make sure the 16-bit app is requesting allowable offsets
  313. // (It's just assertion code, so it doesn't have to be pretty! -JTP)
  314. iOffset = INT32(parg16->f2);
  315. WOW32ASSERT(iOffset >= 0 ||
  316. iOffset == GCL_HBRBACKGROUND ||
  317. iOffset == GCL_HCURSOR ||
  318. iOffset == GCL_HICON ||
  319. iOffset == GCL_HMODULE ||
  320. iOffset == GCL_CBWNDEXTRA ||
  321. iOffset == GCL_CBCLSEXTRA ||
  322. iOffset == GCL_STYLE ||
  323. iOffset == GCW_ATOM);
  324. hwnd = HWND32(parg16->f1);
  325. switch(iOffset) {
  326. case GCL_HBRBACKGROUND:
  327. ul = GetClassLong(hwnd, iOffset);
  328. if (ul > COLOR_ENDCOLORS)
  329. ul = GETHBRUSH16(ul);
  330. break;
  331. case GCL_HCURSOR:
  332. ul = GETHCURSOR16((HAND32)GetClassLong(hwnd, iOffset));
  333. break;
  334. case GCL_HICON:
  335. ul = GETHICON16((HAND32)GetClassLong(hwnd, iOffset));
  336. break;
  337. case GCL_HMODULE:
  338. ul = GetGCL_HMODULE(hwnd);
  339. break;
  340. case GCL_CBWNDEXTRA:
  341. case GCL_STYLE:
  342. ul = GetClassLong(hwnd, iOffset);
  343. break;
  344. case GCL_CBCLSEXTRA:
  345. ul = GetClassLong(hwnd, GCL_CBCLSEXTRA);
  346. break;
  347. default:
  348. ul = GetClassWord(hwnd, iOffset);
  349. break;
  350. }
  351. FREEARGPTR(parg16);
  352. RETURN(ul);
  353. }
  354. /*++
  355. BOOL RegisterClass(<lpWndClass>)
  356. LPWNDCLASS <lpWndClass>;
  357. The %RegisterClass% function registers a window class for subsequent use in
  358. calls to the %CreateWindow% function. The window class has the attributes
  359. defined by the contents of the structure pointed to by the <lpWndClass>
  360. parameter. If two classes with the same name are registered, the second
  361. attempt fails and the information for that class is ignored.
  362. <lpWndClass>
  363. Points to a %WNDCLASS% structure. The structure must be filled with
  364. the appropriate class attributes before being passed to the function.
  365. See the following "Comments" section for details.
  366. The return value specifies whether the window class is registered. It is
  367. TRUE if the class is registered. Otherwise, it is FALSE.
  368. The callback function must use the Pascal calling conventions and must be
  369. declared %FAR%.
  370. Callback Function:
  371. BOOL FAR PASCAL <WndProc>(<hwnd>, <wMsg>, <wParam>, <lParam>)
  372. HWND <hwnd>;
  373. WORD <wMsg>;
  374. WORD<wParam>;
  375. DWORD<lParam>;
  376. <WndProc> is a placeholder for the application-supplied function name. The
  377. actual name must be exported by including it in an %EXPORTS% statement in
  378. the application's module-definition file.
  379. <wMsg>
  380. Specifies the message number.
  381. <wParam>
  382. Specifies additional message-dependent information.
  383. <lParam>
  384. Specifies additional message-dependent information.
  385. The window function returns the result of the message processing. The
  386. possible return values depend on the actual message sent.
  387. --*/
  388. ULONG FASTCALL WU32RegisterClass(PVDMFRAME pFrame)
  389. {
  390. ULONG ul;
  391. WNDCLASS t1;
  392. VPSZ vpszMenu;
  393. PSZ pszMenu;
  394. PSZ pszClass;
  395. register PREGISTERCLASS16 parg16;
  396. CHAR szAtomName[WOWCLASS_ATOM_NAME];
  397. WC wc;
  398. GETARGPTR(pFrame, sizeof(REGISTERCLASS16), parg16);
  399. GETWNDCLASS16(parg16->vpWndClass, &t1);
  400. // Fix up the window words for apps that have hardcode values and did not
  401. // use the value from GetClassInfo when superclassing system proc.
  402. // Some items have been expanded from a WORD to a DWORD bug 22014
  403. // t1.cbWndExtra = (t1.cbWndExtra + 3) & ~3;
  404. vpszMenu = (VPSZ)t1.lpszMenuName;
  405. if (HIWORD(t1.lpszMenuName) != 0) {
  406. GETPSZPTR(t1.lpszMenuName, pszMenu);
  407. t1.lpszMenuName = pszMenu;
  408. }
  409. if (HIWORD(t1.lpszClassName) == 0) {
  410. pszClass = szAtomName;
  411. GetAtomName( (ATOM)t1.lpszClassName, pszClass, WOWCLASS_ATOM_NAME);
  412. } else {
  413. GETPSZPTR(t1.lpszClassName, pszClass);
  414. }
  415. t1.lpszClassName = pszClass;
  416. ul = 0;
  417. wc.vpszMenu = vpszMenu;
  418. wc.iClsExtra = 0;
  419. wc.hMod16 = WOWGetProcModule16((DWORD)t1.lpfnWndProc);
  420. // mark the proc as WOW proc and save the high bits in the RPL
  421. MarkWOWProc(t1.lpfnWndProc,t1.lpfnWndProc);
  422. // Validate hbrBackground, because apps can pass an invalid handle.
  423. // The GetGDI32 returns a non-null value even if h16 is invalid.
  424. //
  425. // if hbrBackground is not valid we set it to NULL if the apps
  426. // ExpWinVer is < 3.1. This behaviour is identical to WIN31 behaviour.
  427. //
  428. // We need to do this validation here because USER32 will fail
  429. // RegisterClass() if hbrBackground is not valid.
  430. //
  431. // known culprits: QuickCase:W (that comes with QcWin)
  432. // class "iconbutton".
  433. if ((DWORD)t1.hbrBackground > (DWORD)(COLOR_ENDCOLORS) &&
  434. GetObjectType(t1.hbrBackground) != OBJ_BRUSH) {
  435. if ((WORD)W32GetExpWinVer((HANDLE) LOWORD(t1.hInstance) ) < 0x030a)
  436. t1.hbrBackground = (HBRUSH)NULL;
  437. }
  438. ul = GETBOOL16((pfnOut.pfnRegisterClassWOWA)(&t1, (DWORD *)&wc));
  439. if (!ul) {
  440. LOGDEBUG(LOG_ALWAYS,("WOW: RegisterClass failed (\"%s\")\n", (LPSZ)pszClass));
  441. // WOW32ASSERT(ul);
  442. }
  443. FREEPSZPTR(pszClass);
  444. FREEPSZPTR(pszMenu);
  445. FREEARGPTR(parg16);
  446. RETURN(ul);
  447. }
  448. /*++
  449. LONG SetClassLong(<hwnd>, <nIndex>, <dwNewLong>)
  450. HWND <hwnd>;
  451. int <nIndex>;
  452. DWORD <dwNewLong>;
  453. The %SetClassLong% function replaces the long value specified by the
  454. <nIndex> parameter in the %WNDCLASS% structure of the window specified by
  455. the <hwnd> parameter.
  456. <hwnd>
  457. Identifies the window.
  458. <nIndex>
  459. Specifies the byte offset of the word to be changed. It can also
  460. be one of the following values:
  461. GCL_MENUNAME
  462. Sets a new long pointer to the menu
  463. GCL_WNDPROC
  464. Sets a new long pointer to the window function.
  465. <dwNewLong>
  466. Specifies the replacement value.
  467. The return value specifies the previous value of the specified long
  468. integer.
  469. If the %SetClassLong% function and GCL_WNDPROC index are used to set a
  470. window function, the given function must have the window-function form and
  471. be exported in the module-definition file. See the %RegisterClass% function
  472. earlier in this chapter for details.
  473. Calling %SetClassLong% with the GCL_WNDPROC index creates a subclass of the
  474. window class that affects all windows subsequently created with the class.
  475. See Chapter 1, Window Manager Interface Functions, for more information on
  476. window subclassing. An application should not attempt to create a window
  477. subclass for standard Windows controls such as combo boxes and buttons.
  478. To access any extra two-byte values allocated when the window-class
  479. structure was created, use a positive byte offset as the index specified by
  480. the <nIndex> parameter, starting at zero for the first two-byte value in the
  481. extra space, 2 for the next two-byte value and so on.
  482. --*/
  483. ULONG FASTCALL WU32SetClassLong(PVDMFRAME pFrame)
  484. {
  485. ULONG ul;
  486. INT iOffset;
  487. PSZ pszMenu;
  488. register PWC pwc;
  489. register PSETCLASSLONG16 parg16;
  490. GETARGPTR(pFrame, sizeof(SETCLASSLONG16), parg16);
  491. // Make sure Win32 didn't change offsets for GCL constants
  492. #if (GCL_MENUNAME != (-8) || GCL_WNDPROC != (-24))
  493. #error Win16/Win32 GCL constants differ
  494. #endif
  495. // Make sure the 16-bit app is requesting allowable offsets
  496. iOffset = INT32(parg16->f2);
  497. WOW32ASSERT(iOffset >= 0 ||
  498. iOffset == GCL_WNDPROC ||
  499. iOffset == GCL_MENUNAME);
  500. ul = 0;
  501. switch (iOffset) {
  502. case GCL_WNDPROC:
  503. {
  504. DWORD dwWndProc32Old;
  505. DWORD dwWndProc32New;
  506. PWW pww;
  507. // Look to see if the new 16:16 proc is a thunk for a 32-bit proc.
  508. dwWndProc32New = IsThunkWindowProc(LONG32(parg16->f3), NULL );
  509. if ( dwWndProc32New != 0 ) {
  510. //
  511. // They are attempting to set the window proc to an existing
  512. // 16-bit thunk that is really just a thunk for a 32-bit
  513. // routine. We can just set it back to the 32-bit routine.
  514. //
  515. dwWndProc32Old = SetClassLong(HWND32(parg16->f1), GCL_WNDPROC, (LONG)dwWndProc32New);
  516. } else {
  517. //
  518. // They are attempting to set it to a real 16:16 proc.
  519. //
  520. LONG l;
  521. l = LONG32(parg16->f3);
  522. // mark the proc as WOW proc and save the high bits in the RPL
  523. MarkWOWProc (l,l);
  524. dwWndProc32Old = SetClassLong(HWND32(parg16->f1), GCL_WNDPROC, l);
  525. }
  526. if ( IsWOWProc (dwWndProc32Old)) {
  527. if ( HIWORD(dwWndProc32Old) == WNDPROC_HANDLE ) {
  528. //
  529. // If the return value is a handle, then just thunk it.
  530. //
  531. pww = FindPWW(HWND32(parg16->f1));
  532. if ( pww == NULL ) {
  533. ul = 0;
  534. } else {
  535. ul = GetThunkWindowProc(dwWndProc32Old, NULL, pww, HWND32(parg16->f1));
  536. }
  537. } else {
  538. //
  539. // Previous proc was a 16:16 proc
  540. // Unmark the proc and restore the high bits from rpl field
  541. UnMarkWOWProc (dwWndProc32Old,ul);
  542. }
  543. } else {
  544. //
  545. // Previous proc was a 32-bit proc, use an allocated thunk
  546. //
  547. pww = FindPWW(HWND32(parg16->f1));
  548. if ( pww == NULL ) {
  549. ul = 0;
  550. } else {
  551. ul = GetThunkWindowProc(dwWndProc32Old, NULL, pww, HWND32(parg16->f1));
  552. }
  553. }
  554. }
  555. break;
  556. case GCL_MENUNAME:
  557. if (pwc = FindPWC(HWND32(parg16->f1))) {
  558. ul = pwc->vpszMenu;
  559. GETPSZPTR(parg16->f3, pszMenu);
  560. SETWC(HWND32(parg16->f1), GCL_WOWMENUNAME, parg16->f3);
  561. SetClassLong(HWND32(parg16->f1), GCL_MENUNAME, (LONG)pszMenu);
  562. FREEPSZPTR(pszMenu);
  563. }
  564. break;
  565. case GCL_CBCLSEXTRA:
  566. // apps shouldn't do this but of course some do!
  567. // (see GCW_CBCLSEXTRA notes in thunk for RegisterClass())
  568. WOW32WARNMSG(0, ("WOW:SetClassLong(): app changing cbClsExtra!"));
  569. // only allow this to be set by classes registered via WOW
  570. if(IsWOWProc (GetClassLong(HWND32(parg16->f1), GCL_WNDPROC))) {
  571. /*
  572. * The hard stuff is now done in User. FritzS
  573. */
  574. ul = SetClassLong(HWND32(parg16->f1), iOffset, WORD32(parg16->f3));
  575. break;
  576. }
  577. else {
  578. ul = 0; // no can do for non-WOW classes
  579. }
  580. break;
  581. default:
  582. ul = SetClassLong(HWND32(parg16->f1), iOffset, LONG32(parg16->f3));
  583. break;
  584. }
  585. FREEARGPTR(parg16);
  586. RETURN(ul);
  587. }
  588. /*++
  589. WORD SetClassWord(<hwnd>, <nIndex>, <wNewWord>)
  590. HWND <hwnd>;
  591. int <nIndex>;
  592. WORD <wNewWord>;
  593. The %SetClassWord% function replaces the word specified by the <nIndex>
  594. parameter in the %WNDCLASS% structure of the window specified by the <hwnd>
  595. parameter.
  596. <hwnd>
  597. Identifies the window.
  598. <nIndex>
  599. Specifies the byte offset of the word to be changed. It can also
  600. be one of the following values:
  601. GCL_CBCLSEXTRA
  602. Sets two new bytes of additional window-class data.
  603. GCL_CBWNDEXTRA
  604. Sets two new bytes of additional window-class data.
  605. GCL_HBRBACKGROUND
  606. Sets a new handle to a background brush.
  607. GCL_HCURSOR
  608. Sets a new handle to a cursor.
  609. GCL_HICON
  610. Sets a new handle to an icon.
  611. GCL_STYLE
  612. Sets a new style bit for the window class.
  613. <wNewWord>
  614. Specifies the replacement value.
  615. The return value specifies the previous value of the specified word.
  616. The %SetClassWord% function should be used with care. For example, it is
  617. possible to change the background color for a class by using %SetClassWord%,
  618. but this change does not cause all windows belonging to the class to be
  619. repainted immediately.
  620. To access any extra four-byte values allocated when the window-class
  621. structure was created, use a positive byte offset as the index specified by
  622. the <nIndex> parameter, starting at zero for the first four-byte value in
  623. the extra space, 4 for the next four-byte value and so on.
  624. --*/
  625. ULONG FASTCALL WU32SetClassWord(PVDMFRAME pFrame)
  626. {
  627. ULONG ul;
  628. HWND hwnd;
  629. INT iOffset;
  630. register PSETCLASSWORD16 parg16;
  631. GETARGPTR(pFrame, sizeof(SETCLASSWORD16), parg16);
  632. // Make sure Win32 didn't change offsets
  633. #if (GCL_HBRBACKGROUND != (-10) || GCL_HCURSOR != (-12) || GCL_HICON != (-14) || GCL_CBWNDEXTRA != (-18) || GCL_CBCLSEXTRA != (-20) || GCL_STYLE != (-26))
  634. #error Win16/Win32 GCW constants differ
  635. #endif
  636. // Make sure the 16-bit app is requesting allowable offsets
  637. // (It's just assertion code, so it doesn't have to be pretty! -JTP)
  638. iOffset = INT32(parg16->f2);
  639. WOW32ASSERT(iOffset >= 0 ||
  640. iOffset == GCL_HBRBACKGROUND ||
  641. iOffset == GCL_HCURSOR ||
  642. iOffset == GCL_HICON ||
  643. iOffset == GCL_CBWNDEXTRA ||
  644. iOffset == GCL_CBCLSEXTRA ||
  645. iOffset == GCL_STYLE)
  646. hwnd = HWND32(parg16->f1);
  647. ul = WORD32(parg16->f3);
  648. switch(iOffset) {
  649. case GCL_HBRBACKGROUND:
  650. if (ul > COLOR_ENDCOLORS)
  651. ul = (LONG) HBRUSH32(ul);
  652. ul = SetClassLong(hwnd, iOffset, (LONG) ul);
  653. if (ul > COLOR_ENDCOLORS)
  654. ul = GETHBRUSH16(ul);
  655. break;
  656. case GCL_HCURSOR:
  657. ul = GETHCURSOR16(SetClassLong(hwnd, iOffset, (LONG)HCURSOR32(ul)));
  658. break;
  659. case GCL_HICON:
  660. ul = GETHICON16(SetClassLong(hwnd, iOffset, (LONG)HICON32(ul)));
  661. break;
  662. case GCL_HMODULE:
  663. ul = 0; // not allowed to set this
  664. break;
  665. case GCL_CBWNDEXTRA:
  666. case GCL_STYLE:
  667. ul = SetClassLong(hwnd, iOffset, (LONG)ul);
  668. break;
  669. case GCL_CBCLSEXTRA:
  670. // apps shouldn't do this but of course some do!
  671. // (see GCW_CBCLSEXTRA notes in thunk for RegisterClass())
  672. WOW32WARNMSG(0, ("WOW:SetClassWord(): app changing cbClsExtra!"));
  673. // only allow this to be set by classes registered via WOW
  674. if(IsWOWProc (GetClassLong(hwnd, GCL_WNDPROC))) {
  675. ul = SetClassLong(hwnd, GCL_CBCLSEXTRA, (LONG)ul);
  676. /*
  677. * The hard work is now done in User. FritzS
  678. */
  679. }
  680. else {
  681. ul = 0; // no can do for non-WOW classes
  682. }
  683. break;
  684. default:
  685. ul = SetClassWord(hwnd, iOffset, (WORD)ul);
  686. break;
  687. }
  688. FREEARGPTR(parg16);
  689. RETURN(ul);
  690. }
  691. /*++
  692. BOOL UnregisterClass(<lpClassName>, <hInstance>)
  693. The %UnregisterClass% function removes the window class specified by
  694. <lpClassName> from the window-class table, freeing the storage required for
  695. the class.
  696. <lpClassName>
  697. Points to a null-terminated string containing the class name. This class
  698. name must have been previously registered by calling the RegisterClass
  699. function with a valid hInstance field in the %WNDCLASS% structure
  700. parameter. Predefined classes, such as dialog-box controls, may not be
  701. unregistered.
  702. <hInstance>
  703. Identifies the instance of the module that created the class.
  704. The return value is TRUE if the function successfully removed the window
  705. class from the window-class table. It is FALSE if the class could not be
  706. found or if a window exists that was created with the class.
  707. Before using this function, destroy all windows created with the specified
  708. class.
  709. --*/
  710. #if 0 // intthunk
  711. ULONG FASTCALL WU32UnregisterClass(PVDMFRAME pFrame)
  712. {
  713. ULONG ul;
  714. PSZ pszClass;
  715. register PUNREGISTERCLASS16 parg16;
  716. GETARGPTR(pFrame, sizeof(UNREGISTERCLASS16), parg16);
  717. GETPSZIDPTR(parg16->vpszClass, pszClass);
  718. ul = GETBOOL16(UnregisterClass(
  719. pszClass,
  720. HMODINST32(parg16->hInstance)
  721. ));
  722. FREEPSZIDPTR(pszClass);
  723. FREEARGPTR(parg16);
  724. RETURN(ul);
  725. }
  726. #endif