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.

589 lines
22 KiB

  1. #include "stdafx.h"
  2. #include "handlers.h"
  3. //-------------------------------------------------------------------------//
  4. // Declare registered message vars **here**
  5. //-------------------------------------------------------------------------//
  6. #define __NO_APPHACKS__
  7. //-------------------------------------------------------------------------//
  8. // Message Handlers
  9. //-------------------------------------------------------------------------//
  10. // Rules for message handlers [scotthan]:
  11. //
  12. // (1) Use DECL_ macros to declare message handler prototype and
  13. // table entries for message handlers below.
  14. // (2) A message handler implementation should NOT:
  15. // 1. call DefWindowProc or CallWindowProc directly,
  16. // but rather use DoMsgDefault().
  17. // 2. delete the incoming CThemeWnd* object,
  18. // (3) A message handler SHOULD:
  19. // 1. Honor the codepage value in the message block when
  20. // handling messages that carry string args.
  21. // If the codepage member is CP_WINUNICODE, the widechar
  22. // string processing should be assumed; otherwise, multibyte
  23. // string processing should be assumed.
  24. // 2. If a message should not be forwarded for default processing,
  25. // mark the message as handled using MsgHandled().
  26. // (4) Handlers should be listed in the BEGIN/ENDMSG() block
  27. // below in decreasing order of expected frequency.
  28. //---------------------//
  29. // WndProc overrides
  30. //---------------------//
  31. // msg handler decls:
  32. DECL_MSGHANDLER( OnOwpPostCreate );
  33. DECL_MSGHANDLER( OnOwpPreStyleChange );
  34. DECL_MSGHANDLER( OnOwpPreWindowPosChanging );
  35. DECL_MSGHANDLER( OnOwpPreWindowPosChanged );
  36. DECL_MSGHANDLER( OnOwpPostWindowPosChanged );
  37. DECL_MSGHANDLER( OnOwpPostSettingChange );
  38. DECL_MSGHANDLER( OnOwpPreMeasureItem );
  39. DECL_MSGHANDLER( OnOwpPreDrawItem );
  40. DECL_MSGHANDLER( OnOwpPreMenuChar );
  41. DECL_MSGHANDLER( OnOwpPostThemeChanged );
  42. DECL_MSGHANDLER( OnOwpPreNcPaint );
  43. DECL_MSGHANDLER( OnOwpPostNcPaint );
  44. // handler table:
  45. BEGIN_HANDLER_TABLE(_rgOwpHandlers)
  46. // frequent messages
  47. DECL_MSGENTRY( WM_NCPAINT, OnOwpPreNcPaint, OnOwpPostNcPaint )
  48. DECL_MSGENTRY( WM_WINDOWPOSCHANGING, OnOwpPreWindowPosChanging, NULL )
  49. DECL_MSGENTRY( WM_WINDOWPOSCHANGED, OnOwpPreWindowPosChanged, OnOwpPostWindowPosChanged )
  50. DECL_MSGENTRY( WM_SETTINGCHANGE, NULL, OnOwpPostSettingChange )
  51. DECL_MSGENTRY( WM_MEASUREITEM, OnOwpPreMeasureItem, NULL )
  52. DECL_MSGENTRY( WM_DRAWITEM, OnOwpPreDrawItem, NULL )
  53. DECL_MSGENTRY( WM_MDISETMENU, NULL, NULL )
  54. // rare messages:
  55. DECL_MSGENTRY( WM_MENUCHAR, OnOwpPreMenuChar, NULL )
  56. DECL_MSGENTRY( WM_STYLECHANGING, OnOwpPreStyleChange, NULL )
  57. DECL_MSGENTRY( WM_STYLECHANGED, OnOwpPreStyleChange, NULL )
  58. DECL_MSGENTRY( WM_NCCREATE, NULL, NULL )
  59. DECL_MSGENTRY( WM_CREATE, NULL, OnOwpPostCreate )
  60. DECL_MSGENTRY( WM_NCDESTROY, NULL, NULL )
  61. DECL_MSGENTRY( WM_THEMECHANGED, NULL, OnOwpPostThemeChanged ) // we handle in line in ThemePreWndProc()
  62. DECL_MSGENTRY( WM_THEMECHANGED_TRIGGER, NULL, NULL ) // we handle in line in ThemePreWndProc()
  63. END_HANDLER_TABLE()
  64. // Note: values of high owp message must be in sync w/ table.
  65. #define WNDPROC_MSG_LAST WM_THEMECHANGED_TRIGGER // 0x031B (alias for WM_UAHINIT)
  66. //------------------------//
  67. // DefDlgProc overrides
  68. //------------------------//
  69. // msg handler decls:
  70. DECL_MSGHANDLER( OnDdpPostCtlColor );
  71. DECL_MSGHANDLER( OnDdpCtlColor );
  72. DECL_MSGHANDLER( OnDdpPrint );
  73. DECL_MSGHANDLER( OnDdpPostInitDialog );
  74. // handler table:
  75. BEGIN_HANDLER_TABLE(_rgDdpHandlers)
  76. // frequent messages:
  77. DECL_MSGENTRY( WM_CTLCOLORDLG, NULL, OnDdpPostCtlColor )
  78. DECL_MSGENTRY( WM_CTLCOLORSTATIC, NULL, OnDdpCtlColor)
  79. DECL_MSGENTRY( WM_CTLCOLORBTN, NULL, OnDdpCtlColor)
  80. DECL_MSGENTRY( WM_CTLCOLORMSGBOX, NULL, OnDdpPostCtlColor )
  81. DECL_MSGENTRY( WM_PRINTCLIENT, NULL, OnDdpPrint )
  82. // rare messages:
  83. DECL_MSGENTRY( WM_INITDIALOG, NULL, OnDdpPostInitDialog )
  84. END_HANDLER_TABLE()
  85. // Note: values of high ddp message must be in sync w/ table.
  86. #define DEFDLGPROC_MSG_LAST WM_PRINTCLIENT // 0x0318
  87. //--------------------------//
  88. // DefWindowProc override
  89. //--------------------------//
  90. // msg handler decls:
  91. DECL_MSGHANDLER( OnDwpNcPaint );
  92. DECL_MSGHANDLER( OnDwpNcHitTest );
  93. DECL_MSGHANDLER( OnDwpNcActivate );
  94. DECL_MSGHANDLER( OnDwpNcLButtonDown );
  95. DECL_MSGHANDLER( OnDwpNcThemeDrawCaption );
  96. DECL_MSGHANDLER( OnDwpNcThemeDrawFrame );
  97. DECL_MSGHANDLER( OnDwpNcMouseMove );
  98. DECL_MSGHANDLER( OnDwpNcMouseLeave );
  99. DECL_MSGHANDLER( OnDwpWindowPosChanged );
  100. DECL_MSGHANDLER( OnDwpSysCommand );
  101. DECL_MSGHANDLER( OnDwpSetText );
  102. DECL_MSGHANDLER( OnDwpSetIcon );
  103. DECL_MSGHANDLER( OnDwpStyleChanged );
  104. DECL_MSGHANDLER( OnDwpPrint );
  105. DECL_MSGHANDLER( OnDwpPrintClient );
  106. DECL_MSGHANDLER( OnDwpContextMenu );
  107. // handler table:
  108. BEGIN_HANDLER_TABLE(_rgDwpHandlers)
  109. // frequent messages:
  110. DECL_MSGENTRY( WM_NCHITTEST, OnDwpNcHitTest, NULL )
  111. DECL_MSGENTRY( WM_NCPAINT, OnDwpNcPaint, NULL )
  112. DECL_MSGENTRY( WM_NCACTIVATE, OnDwpNcActivate, NULL )
  113. DECL_MSGENTRY( WM_NCMOUSEMOVE, OnDwpNcMouseMove, NULL )
  114. DECL_MSGENTRY( WM_NCMOUSELEAVE, OnDwpNcMouseLeave, NULL )
  115. DECL_MSGENTRY( WM_WINDOWPOSCHANGED, OnDwpWindowPosChanged, NULL )
  116. DECL_MSGENTRY( WM_SYSCOMMAND, OnDwpSysCommand, NULL )
  117. DECL_MSGENTRY( WM_NCLBUTTONDOWN, OnDwpNcLButtonDown, NULL )
  118. DECL_MSGENTRY( WM_NCUAHDRAWCAPTION, OnDwpNcThemeDrawCaption, NULL )
  119. DECL_MSGENTRY( WM_NCUAHDRAWFRAME, OnDwpNcThemeDrawFrame, NULL )
  120. DECL_MSGENTRY( WM_PRINT, OnDwpPrint, NULL )
  121. DECL_MSGENTRY( WM_PRINTCLIENT, OnDwpPrintClient, NULL )
  122. DECL_MSGENTRY( WM_CTLCOLORMSGBOX, OnDdpPostCtlColor, NULL) // Strange: Sent to DefWindowProc, but is a Dialog message
  123. DECL_MSGENTRY( WM_CTLCOLORSTATIC, OnDdpCtlColor, NULL)
  124. DECL_MSGENTRY( WM_CTLCOLORBTN, OnDdpCtlColor, NULL)
  125. // rare messages:
  126. DECL_MSGENTRY( WM_SETTEXT, OnDwpSetText, NULL )
  127. DECL_MSGENTRY( WM_SETICON, OnDwpSetIcon, NULL )
  128. DECL_MSGENTRY( WM_STYLECHANGED, OnDwpStyleChanged, NULL )
  129. DECL_MSGENTRY( WM_CONTEXTMENU, OnDwpContextMenu, NULL )
  130. DECL_MSGENTRY( WM_THEMECHANGED_TRIGGER, NULL, NULL )
  131. DECL_MSGENTRY( WM_NCDESTROY, NULL, NULL )
  132. END_HANDLER_TABLE()
  133. // Note: values of high dwp message must be in sync w/ handler table.
  134. #define DEFWNDPROC_MSG_LAST WM_THEMECHANGED_TRIGGER // 0x031B
  135. //---------------------------------------------------------------------------
  136. BOOL _FindMsgHandler( UINT, MSGENTRY [], int, IN HOOKEDMSGHANDLER*, IN HOOKEDMSGHANDLER* );
  137. BOOL _SetMsgHandler( UINT, MSGENTRY [], int, IN HOOKEDMSGHANDLER, BOOL );
  138. //---------------------------------------------------------------------------
  139. // Special case hook handling
  140. //---------------------------------------------------------------------------
  141. //---------------------------------------------------------------------------
  142. BOOL _IsExcludedSystemProcess( LPCWSTR pszProcess )
  143. {
  144. static const WCHAR* _rgszSystemProcessList[] =
  145. {
  146. L"lsass", // Local Security Authority sub-system
  147. L"services", // Service Control Manager
  148. L"svchost", // Service Host
  149. L"mstask", // Microsoft Task Scheduler
  150. L"dfssvc", // Distributed File System Service
  151. L"winmgmt", // Windows Management Instrumentation
  152. L"spoolsv", // Print Spool Service
  153. L"msdtc", // Microsoft Distributed Transaction Co-ordinator
  154. L"regsvc", // Remote Registry Service
  155. L"webclnt", // Web Client
  156. L"mspmspsv", // WMDM PMSP Service (what is this?)
  157. L"ntvdm" // NT virtual DOS machine
  158. };
  159. return AsciiScanStringList( pszProcess, _rgszSystemProcessList,
  160. ARRAYSIZE(_rgszSystemProcessList), TRUE );
  161. }
  162. //---------------------------------------------------------------------------
  163. BOOL _IsProcessOnInteractiveWindowStation() // check if we're on winsta0.
  164. {
  165. BOOL fRet = FALSE;
  166. HWINSTA hWinSta = GetProcessWindowStation();
  167. if( hWinSta != NULL )
  168. {
  169. DWORD cbLength = 0;
  170. WCHAR wszName[0xFF];
  171. WCHAR* pszName = wszName;
  172. GetUserObjectInformationW(hWinSta, UOI_NAME, NULL, 0, &cbLength);
  173. if( cbLength < sizeof(wszName) )
  174. {
  175. pszName = (WCHAR*)LocalAlloc(LMEM_FIXED, cbLength);
  176. if( NULL == pszName )
  177. return FALSE;
  178. }
  179. if (pszName != NULL)
  180. {
  181. if( GetUserObjectInformationW(hWinSta, UOI_NAME, pszName, cbLength, &cbLength) != FALSE )
  182. {
  183. fRet = (0 == AsciiStrCmpI(pszName, L"winsta0"));
  184. }
  185. if( pszName != wszName )
  186. LocalFree(pszName);
  187. }
  188. }
  189. return(fRet);
  190. }
  191. //---------------------------------------------------------------------------
  192. BOOL _IsWin16App() // check if this is a 16-bit process
  193. {
  194. GUITHREADINFO gti;
  195. gti.cbSize = sizeof(gti);
  196. gti.flags = GUI_16BITTASK;
  197. return GetGUIThreadInfo( GetCurrentThreadId(), &gti ) &&
  198. TESTFLAG(gti.flags, GUI_16BITTASK );
  199. }
  200. //---------------------------------------------------------------------------
  201. BOOL ApiHandlerInit( const LPCTSTR pszProcess, USERAPIHOOK* puahTheme, const USERAPIHOOK* puahReal )
  202. {
  203. // exclude known non-UI system processes
  204. if( _IsExcludedSystemProcess( pszProcess ) )
  205. return FALSE;
  206. // exclude any process not hosted on winsta0.
  207. if( !_IsProcessOnInteractiveWindowStation() )
  208. return FALSE;
  209. if( _IsWin16App() )
  210. return FALSE;
  211. // SHIMSHIM [scotthan]:
  212. #ifdef _DEBUG
  213. //---- temp patch against msvcmon ----
  214. if( 0 == AsciiStrCmpI(pszProcess, L"msvcmon") )
  215. {
  216. return FALSE;
  217. }
  218. //---- temp patch against msdev ----
  219. if( 0 == AsciiStrCmpI(pszProcess, L"msdev") )
  220. {
  221. return FALSE;
  222. }
  223. //---- Aid in debugging classic/themed differences: ---
  224. if( 0 == AsciiStrCmpI( pszProcess, L"mditest1" ) )
  225. {
  226. return FALSE;
  227. }
  228. #endif
  229. #ifndef __NO_APPHACKS__
  230. static const WCHAR* _rgszExcludeAppList[] =
  231. {
  232. #ifdef THEME_CALCSIZE
  233. // Invoking SetWindowPos from CThemeWnd::SetFrameTheme on our Post-WM_CREATE handler
  234. // causes emacs to divide by zero after receiving meaningless rects from two
  235. // successive calls to AdjustWindowRectEx from his WM_WINDOWPOSCHANGING handler.
  236. // I don't believe it is related to the fact that AdjustWindowRectEx has yet
  237. // to be implemented for themed windows (raid# 140989), but rather that the wndproc
  238. // is not ready for a WM_WINDOWPOSCHANGING message on the abrubtly on the
  239. // heels of a WM_CREATE handler.
  240. L"emacs",
  241. L"neoplanet", // 247283: We rush in to theme neoplanet's dialogs, which we almost
  242. L"np", // immediately revoke, but not before sizing the dialog to theme-compatible
  243. // client rect. When we withdraw, we leave it clipped. No good way to deal
  244. // with this for beta2.
  245. // HTML Editor++ v.8: 286676:
  246. // This guy recomputes his nonclient area, and then AVs dereferencing a
  247. // WM_WINDOWPOSCHANGING message under themes.
  248. L"coffee",
  249. #endif THEME_CALCSIZE
  250. L"refcntr", // 205059: Corel Reference Center; lower 10% of window is clipped.
  251. L"KeyFramerPro", // 336456: Regardless of whether themes are enabled, Boris KeyFramer Pro v.5
  252. // does two SetWindowRgn() calls for every WM_PAINT, the first with a region,
  253. // the next with NULL, Is the app trying to clip his painting?
  254. // If so, this is not what SetWindowRgn was intended for, and explains why this
  255. // app is so clunky at window resizing. Rather, SelectClipRgn is the
  256. // correct API.
  257. // When themes are enabled, we keep revoking and re-attatching with each
  258. // SetWindowRgn call, so we get substantial flicker.
  259. // The ISV should be notified of this bug.
  260. // Applications that do custom non-client painting and hence look broken when
  261. // themed. Our only recourse at the moment it to exclude them from non-client
  262. // themeing so that we don't stomp whatever they are trying to do.
  263. L"RealJBox", // 273370: Real JukeBox
  264. L"RealPlay", // 285368: Real AudioPlayer
  265. L"TeamMgr", // 286654: Microsoft Team Manager97
  266. L"TrpMaker", // 307107: Rand McNally TripMaker 2000
  267. L"StrFindr", // 307535: Rand McNally StreetFinder 2000
  268. L"Exceed", // 276244: Hummingbird Exceed 6.2/7.0
  269. L"VP30", // 328676: Intel Video Phone
  270. // 313407: Groove, build 760
  271. // Calls DefWindowProc for NCPAINT, then paints his own caption over it.
  272. // Note: this just might work correctly if we had a DrawFrameControl hook.
  273. L"groove", // filever 1.1.0.760, 1/22/2001 tested.
  274. // 303756: Exclude all Lotus SmartSuite apps to provide consistency among their
  275. // apps. All of them draw into the caption bar.
  276. L"WordPro", // 285065: Lotus WordPro, a particularly poorly implemented app.
  277. L"SmartCtr", // It's WordPerfect compat menu is the elephant man of modern software.
  278. L"123w",
  279. L"Approach",
  280. L"FastSite",
  281. L"F32Main",
  282. L"Org5",
  283. // 358337: Best Technology - GCC Developer Lite. Custom caption bar fights with Luna.
  284. L"GCCDevL", // install point: http://www.besttechnology.co.jp/download/GDL1_0_3_6.EXE
  285. // 360422: J Zenrin The Real Digital Map Z3(T1):Max/Min/Close buttons are overlapped on classic buttons in title bar.
  286. L"emZmain",
  287. // 364337: Encarta World English Dictionary: Luna system buttons are overlaid on top of app's custom ones when mousing over
  288. L"ewed.exe",
  289. // 343171: Reaktor Realtime Instrument: pressing the close button while themed causes this app to
  290. // spin in a tight loop running at realtime priority, effectively hanging the machine.
  291. // The message loop for this app is extremely timing sensitive, the additional overhead
  292. // introduced by theming alters the timing enough to break this app.
  293. L"Reaktor",
  294. };
  295. if( AsciiScanStringList( pszProcess, _rgszExcludeAppList,
  296. ARRAYSIZE(_rgszExcludeAppList), TRUE ) )
  297. {
  298. return FALSE;
  299. }
  300. #ifdef THEME_CALCSIZE
  301. // Winstone 99 needs modified NC_CALCSIZE behavior for Netscape or it will hang.
  302. if ( 0 == AsciiStrCmpI( pszProcess, L"Netscape" ))
  303. {
  304. if (FindWindowEx(NULL, NULL, L"ZDBench32Frame", NULL) != NULL)
  305. {
  306. _SetMsgHandler( WM_NCCALCSIZE, _rgDwpHandlers, ARRAYSIZE(_rgDwpHandlers),
  307. OnDwpNcCalcSize2, FALSE );
  308. return TRUE;
  309. }
  310. }
  311. #endif THEME_CALCSIZE
  312. //-------------------------
  313. // This AppHack was once fixed, but got broke again with
  314. // addition of logic for partial-screen maximized windows.
  315. //
  316. // Something in our answer to NCCALCSIZE causes quick time player
  317. // to continously flood its 'control' frame window's winproc with
  318. // WM_PAINTS by repeatedly calling InvalidateRgn + UpdateWindow. My
  319. // suspicion is that he looks at what DefWindowProc returns from
  320. // NCCALCSIZE to determine the area he needs to manage, and when
  321. // this doesn't hash with other SYSMET values and/or AdjustWindowRect,
  322. // he redundantly invalidates himself,
  323. //
  324. // This only repros if qtp is launched w/ .mov file, works fine if
  325. // launched without a file and then a file is loaded.
  326. #ifdef THEME_CALCSIZE
  327. if( 0 == AsciiStrCmpI( pszProcess, L"QuickTimePlayer" ))
  328. {
  329. _SetMsgHandler( WM_NCCALCSIZE, _rgDwpHandlers, ARRAYSIZE(_rgDwpHandlers),
  330. OnDwpNcCalcSize2, FALSE );
  331. return TRUE;
  332. }
  333. // SEANHI DID NOT RECEIVE THE S/W FROM APPLIB AND SO WAS UNABLE TO VERIFY THIS
  334. // NO LONGER REPROS W/ ELIMINATION OF THEMED SYSMETS
  335. //-------------------------
  336. // Paradox 9 appHack for nonclient button sizes:
  337. //
  338. // Paradox table schema view uses DrawFrameControl to render both
  339. // a classic toolframe (small) caption and buttons, but uses the
  340. // themed values of SM_CYSIZE instead of SM_CYSMSIZE to size the buttons.
  341. // This apphack redirects requests in this process for SM_CX/YSIZE to SM_CX/YSMSIZE.
  342. if( 0 == AsciiStrCmpI( pszProcess, L"pdxwin32" ) )
  343. {
  344. _SetGsmHandler( SM_CXSIZE, OnGsmCxSmBtnSize );
  345. _SetGsmHandler( SM_CYSIZE, OnGsmCySmBtnSize );
  346. return TRUE;
  347. }
  348. #endif THEME_CALCSIZE
  349. //-------------------------
  350. #else
  351. # pragma message("App hacks disabled")
  352. #endif __NO_APPHACKS__
  353. return TRUE;
  354. }
  355. //---------------------------------------------------------------------------
  356. // Handler table utility functions
  357. //---------------------------------------------------------------------------
  358. //---------------------------------------------------------------------------
  359. void HandlerTableInit() {}
  360. //---------------------------------------------------------------------------
  361. BOOL _InitMsgMask( LPBYTE prgMsgMask, DWORD dwMaskBytes, MSGENTRY* prgEntries, int cEntries,
  362. IN OUT BOOL& fInit )
  363. {
  364. if( !fInit )
  365. {
  366. for( int i = 0; i < cEntries; i++ )
  367. {
  368. if( -1 == prgEntries[i].nMsg )
  369. {
  370. ASSERT(prgEntries[i].pnRegMsg);
  371. // Initialize registered message entry
  372. prgEntries[i].nMsg = *prgEntries[i].pnRegMsg;
  373. Log(LOG_TMHANDLE, L"InitMsgMsg corrected registered msg: 0x%x", prgEntries[i].nMsg);
  374. }
  375. //---- ensure we set up limit on table correctly ----
  376. ASSERT((prgEntries[i].nMsg)/8 < dwMaskBytes);
  377. SET_MSGMASK( prgMsgMask, prgEntries[i].nMsg );
  378. }
  379. fInit = TRUE;
  380. }
  381. return fInit;
  382. }
  383. //---------------------------------------------------------------------------
  384. // Scan of MSG table as linear array:
  385. inline int _FindMsgHandler(
  386. UINT nMsg,
  387. MSGENTRY rgEntries[],
  388. int cEntries,
  389. OUT OPTIONAL HOOKEDMSGHANDLER* ppfnHandler,
  390. OUT OPTIONAL HOOKEDMSGHANDLER* ppfnHandler2 )
  391. {
  392. ASSERT( nMsg );
  393. ASSERT( nMsg != (UINT)-1 );
  394. if( ppfnHandler ) *ppfnHandler = NULL;
  395. if( ppfnHandler2 ) *ppfnHandler2 = NULL;
  396. for( int i = 0; i < cEntries; i++ )
  397. {
  398. if( rgEntries[i].nMsg == nMsg )
  399. {
  400. // If no handler requested, return success
  401. if( NULL == ppfnHandler && NULL == ppfnHandler2 )
  402. return i;
  403. // Assign outbound handler values
  404. if( ppfnHandler ) *ppfnHandler = rgEntries[i].pfnHandler;
  405. if( ppfnHandler2 ) *ppfnHandler2 = rgEntries[i].pfnHandler2;
  406. // return TRUE iif caller got what he asked for.
  407. return ((ppfnHandler && *ppfnHandler) || (ppfnHandler2 && *ppfnHandler2)) ? i : -1;
  408. }
  409. }
  410. return -1;
  411. }
  412. //---------------------------------------------------------------------------
  413. // Modify existing handler
  414. inline BOOL _SetMsgHandler(
  415. UINT nMsg,
  416. MSGENTRY rgEntries[],
  417. int cEntries,
  418. IN HOOKEDMSGHANDLER pfnHandler,
  419. BOOL fHandler2 )
  420. {
  421. int i = _FindMsgHandler( nMsg, rgEntries, cEntries, NULL, NULL );
  422. if( i >= 0 )
  423. {
  424. if( fHandler2 )
  425. rgEntries[i].pfnHandler2 = pfnHandler;
  426. else
  427. rgEntries[i].pfnHandler = pfnHandler;
  428. return TRUE;
  429. }
  430. return FALSE;
  431. }
  432. #define CBMSGMASK(msgHigh) (((msgHigh)+1)/8 + ((((msgHigh)+1) % 8) ? 1: 0))
  433. //---------------------------------------------------------------------------
  434. DWORD GetOwpMsgMask( LPBYTE* prgMsgMask )
  435. {
  436. static BOOL _fOwpMask = FALSE; // initialized?
  437. static BYTE _rgOwpMask[CBMSGMASK(WNDPROC_MSG_LAST)] = {0};
  438. if( _InitMsgMask( _rgOwpMask, ARRAYSIZE(_rgOwpMask), _rgOwpHandlers, ARRAYSIZE(_rgOwpHandlers), _fOwpMask ) )
  439. {
  440. *prgMsgMask = _rgOwpMask;
  441. return ARRAYSIZE(_rgOwpMask);
  442. }
  443. return 0;
  444. }
  445. //---------------------------------------------------------------------------
  446. DWORD GetDdpMsgMask( LPBYTE* prgMsgMask )
  447. {
  448. static BOOL _fDdpMask = FALSE; // initialized?
  449. static BYTE _rgDdpMask[CBMSGMASK(DEFDLGPROC_MSG_LAST)] = {0};
  450. if( _InitMsgMask( _rgDdpMask, ARRAYSIZE(_rgDdpMask), _rgDdpHandlers, ARRAYSIZE(_rgDdpHandlers), _fDdpMask ) )
  451. {
  452. *prgMsgMask = _rgDdpMask;
  453. return ARRAYSIZE(_rgDdpMask);
  454. }
  455. return 0;
  456. }
  457. //---------------------------------------------------------------------------
  458. DWORD GetDwpMsgMask( LPBYTE* prgMsgMask )
  459. {
  460. static BOOL _fDwpMask = FALSE; // initialized?
  461. static BYTE _rgDwpMask[CBMSGMASK(DEFWNDPROC_MSG_LAST)] = {0};
  462. if( _InitMsgMask( _rgDwpMask, ARRAYSIZE(_rgDwpMask), _rgDwpHandlers, ARRAYSIZE(_rgDwpHandlers), _fDwpMask ) )
  463. {
  464. *prgMsgMask = _rgDwpMask;
  465. return ARRAYSIZE(_rgDwpMask);
  466. }
  467. return 0;
  468. }
  469. //---------------------------------------------------------------------------
  470. BOOL FindOwpHandler(
  471. UINT nMsg, HOOKEDMSGHANDLER* ppfnPre, HOOKEDMSGHANDLER* ppfnPost )
  472. {
  473. return _FindMsgHandler( nMsg, _rgOwpHandlers, ARRAYSIZE(_rgOwpHandlers),
  474. ppfnPre, ppfnPost ) >= 0;
  475. }
  476. //---------------------------------------------------------------------------
  477. BOOL FindDdpHandler(
  478. UINT nMsg, HOOKEDMSGHANDLER* ppfnPre, HOOKEDMSGHANDLER* ppfnPost )
  479. {
  480. return _FindMsgHandler( nMsg, _rgDdpHandlers, ARRAYSIZE(_rgDdpHandlers),
  481. ppfnPre, ppfnPost ) >= 0;
  482. }
  483. //---------------------------------------------------------------------------
  484. BOOL FindDwpHandler( UINT nMsg, HOOKEDMSGHANDLER* ppfnPre )
  485. {
  486. HOOKEDMSGHANDLER pfnPost;
  487. return _FindMsgHandler( nMsg, _rgDwpHandlers, ARRAYSIZE(_rgDwpHandlers),
  488. ppfnPre, &pfnPost ) >= 0;
  489. }
  490. //---------------------------------------------------------------------------
  491. // Performs default message processing.
  492. LRESULT WINAPI DoMsgDefault( const THEME_MSG *ptm )
  493. {
  494. ASSERT( ptm );
  495. if( ptm->pfnDefProc )
  496. {
  497. MsgHandled( ptm );
  498. if( MSGTYPE_DEFWNDPROC == ptm->type )
  499. return ptm->pfnDefProc( ptm->hwnd, ptm->uMsg, ptm->wParam, ptm->lParam );
  500. else
  501. {
  502. ASSERT( NULL == ptm->pfnDefProc ); // bad initialization (_InitThemeMsg)
  503. }
  504. }
  505. return 0L;
  506. }