Leaked source code of windows server 2003
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.

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