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.

154 lines
4.5 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 "priv.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. STDAPI_(BOOL) SHMirrorIcon(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. if (!g_bMirroredOS)
  35. {
  36. return FALSE;
  37. }
  38. //
  39. // Synchronize access to global DCs now!
  40. // Allocate DCs if we didn't so far.
  41. //
  42. ENTERCRITICAL;
  43. if (!g_hdc && !g_hdcMask)
  44. {
  45. g_hdc = CreateCompatibleDC(NULL);
  46. if (g_hdc)
  47. {
  48. g_hdcMask = CreateCompatibleDC(NULL);
  49. if( g_hdcMask )
  50. {
  51. SET_DC_RTL_MIRRORED(g_hdc);
  52. SET_DC_RTL_MIRRORED(g_hdcMask);
  53. }
  54. else
  55. {
  56. DeleteDC( g_hdc );
  57. g_hdc = NULL;
  58. }
  59. }
  60. }
  61. if (phiconSmall)
  62. hicon[0] = *phiconSmall;
  63. if (phiconLarge)
  64. hicon[1] = *phiconLarge;
  65. //
  66. // Acquire screen DC
  67. //
  68. hdcScreen = GetDC(NULL);
  69. if (g_hdc && g_hdcMask && hdcScreen)
  70. {
  71. for( i=0 ; i<(sizeof(hicon)/sizeof(hicon[0])) ; i++ )
  72. {
  73. if( hicon[i] )
  74. {
  75. if( GetIconInfo(hicon[i], &ii) &&
  76. GetObjectWrapW(ii.hbmColor, sizeof(bm), &bm))
  77. {
  78. //
  79. // I don't want these.
  80. //
  81. DeleteObject( ii.hbmMask );
  82. DeleteObject( ii.hbmColor );
  83. ii.hbmMask = ii.hbmColor = NULL;
  84. hbm = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
  85. hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
  86. hbmOld = (HBITMAP)SelectObject(g_hdc, hbm);
  87. hbmOldMask = (HBITMAP)SelectObject(g_hdcMask, hbmMask);
  88. DrawIconEx(g_hdc, 0, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0,
  89. NULL, DI_IMAGE);
  90. DrawIconEx(g_hdcMask, 0, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0,
  91. NULL, DI_MASK);
  92. SelectObject(g_hdc, hbmOld);
  93. SelectObject(g_hdcMask, hbmOldMask);
  94. //
  95. // create the new mirrored icon, and delete bmps
  96. //
  97. ii.hbmMask = hbmMask;
  98. ii.hbmColor = hbm;
  99. hiconNew[i] = CreateIconIndirect(&ii);
  100. DeleteObject(hbm);
  101. DeleteObject(hbmMask);
  102. }
  103. }
  104. }
  105. }
  106. ReleaseDC(NULL, hdcScreen);
  107. //
  108. // Now we can reuse the global DCs
  109. //
  110. LEAVECRITICAL;
  111. //
  112. // Update icons if needed, and destroy old ones!
  113. //
  114. if (hicon[0] && hiconNew[0])
  115. {
  116. *phiconSmall = hiconNew[0];
  117. DestroyIcon(hicon[0]);
  118. }
  119. if (hicon[1] && hiconNew[1])
  120. {
  121. *phiconLarge = hiconNew[1];
  122. //
  123. // Don't delete twice
  124. //
  125. if (hicon[1] != hicon[0])
  126. DestroyIcon(hicon[1]);
  127. }
  128. return TRUE;
  129. }