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.

167 lines
4.8 KiB

  1. /****************************** Module*Header *****************************\
  2. * Module Name: mirror.c *
  3. * *
  4. * This module contains all the Right-To-Left (RTL) Mirroring support *
  5. * routines used to Right-To-Left mirror an icon on the fly so that *
  6. * it would be displayed normal on a RTL mirrored localized OS. This is *
  7. * mainly a concern for 3rd party Apps. *
  8. * *
  9. * *
  10. * Created: 01-Feb-1998 8:41:18 pm *
  11. * Author: Samer Arafeh [samera] *
  12. * *
  13. * Copyright (c) 1998 Microsoft Corporation *
  14. \**************************************************************************/
  15. #include "ctlspriv.h"
  16. /***************************************************************************\
  17. * MirrorIcon
  18. *
  19. * Mirror an Icon , given an Icon handle so that when these icons are displayed
  20. * on a Mirrored DC, they end would be displayed normal.
  21. *
  22. * History:
  23. * 04-Feb-1998 samera Created
  24. \***************************************************************************/
  25. BOOL WINAPI MirrorIcon(HICON* phiconSmall, HICON* phiconLarge)
  26. {
  27. HDC hdcScreen;
  28. HBITMAP hbm, hbmMask, hbmOld,hbmOldMask;
  29. BITMAP bm;
  30. HICON hicon[2] = {NULL,NULL};
  31. HICON hiconNew[2] = {NULL,NULL};
  32. ICONINFO ii ;
  33. int i;
  34. #ifdef WINNT
  35. #define IPIXELOFFSET 0
  36. #else // !WINNT
  37. #define IPIXELOFFSET 2
  38. #endif WINNT
  39. //
  40. // Synchronize access to global DCs now!
  41. // Allocate DCs if we didn't so far.
  42. //
  43. ENTERCRITICAL;
  44. if (!g_hdc && !g_hdcMask)
  45. {
  46. g_hdc = CreateCompatibleDC(NULL);
  47. if (g_hdc)
  48. {
  49. #ifndef UNIX
  50. #ifndef WINNT
  51. SetObjectOwner(g_hdc, HINST_THISDLL);
  52. #endif
  53. #endif /* !UNIX */
  54. g_hdcMask = CreateCompatibleDC(NULL);
  55. if( g_hdcMask )
  56. {
  57. #ifndef UNIX
  58. #ifndef WINNT
  59. SetObjectOwner(g_hdcMask, HINST_THISDLL);
  60. #endif
  61. #endif /* !UNIX */
  62. SET_DC_RTL_MIRRORED(g_hdc);
  63. SET_DC_RTL_MIRRORED(g_hdcMask);
  64. }
  65. else
  66. {
  67. DeleteDC( g_hdc );
  68. g_hdc = NULL;
  69. }
  70. }
  71. }
  72. if (phiconSmall)
  73. hicon[0] = *phiconSmall;
  74. if (phiconLarge)
  75. hicon[1] = *phiconLarge;
  76. //
  77. // Acquire the screen DC
  78. //
  79. hdcScreen = GetDC(NULL);
  80. if (g_hdc && g_hdcMask && hdcScreen)
  81. {
  82. for( i=0 ; i<(sizeof(hicon)/sizeof(HICON)) ; i++ )
  83. {
  84. if( hicon[i] )
  85. {
  86. if( GetIconInfo(hicon[i], &ii) &&
  87. GetObject(ii.hbmColor, sizeof(BITMAP), &bm))
  88. {
  89. //
  90. // I don't want these.
  91. //
  92. DeleteObject( ii.hbmMask );
  93. DeleteObject( ii.hbmColor );
  94. ii.hbmMask = ii.hbmColor = NULL;
  95. hbm = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
  96. hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
  97. hbmOld = (HBITMAP)SelectObject(g_hdc, hbm);
  98. hbmOldMask = (HBITMAP)SelectObject(g_hdcMask, hbmMask);
  99. DrawIconEx(g_hdc, IPIXELOFFSET, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0,
  100. NULL, DI_IMAGE);
  101. DrawIconEx(g_hdcMask, IPIXELOFFSET, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0,
  102. NULL, DI_MASK);
  103. SelectObject(g_hdc, hbmOld);
  104. SelectObject(g_hdcMask, hbmOldMask);
  105. //
  106. // create the new mirrored icon, and delete bmps
  107. //
  108. ii.hbmMask = hbmMask;
  109. ii.hbmColor = hbm;
  110. hiconNew[i] = CreateIconIndirect(&ii);
  111. DeleteObject(hbm);
  112. DeleteObject(hbmMask);
  113. }
  114. }
  115. }
  116. }
  117. ReleaseDC(NULL, hdcScreen);
  118. //
  119. // Now we can reuse the global DCs
  120. //
  121. LEAVECRITICAL;
  122. //
  123. // Update icons if needed, and destroy old ones!
  124. //
  125. if (hicon[0] && hiconNew[0])
  126. {
  127. *phiconSmall = hiconNew[0];
  128. DestroyIcon(hicon[0]);
  129. }
  130. if (hicon[1] && hiconNew[1])
  131. {
  132. *phiconLarge = hiconNew[1];
  133. //
  134. // Don't delete twice
  135. //
  136. if (hicon[1] != hicon[0])
  137. DestroyIcon(hicon[1]);
  138. }
  139. return TRUE;
  140. }