/****************************** Module*Header *****************************\ * Module Name: mirror.c * * * * This module contains all the Right-To-Left (RTL) Mirroring support * * routines used to Right-To-Left mirror an icon on the fly so that * * it would be displayed normal on a RTL mirrored localized OS. This is * * mainly a concern for 3rd party Apps. * * * * * * Created: 01-Feb-1998 8:41:18 pm * * Author: Samer Arafeh [samera] * * * * Copyright (c) 1998 Microsoft Corporation * \**************************************************************************/ #include "ctlspriv.h" /***************************************************************************\ * MirrorIcon * * Mirror an Icon , given an Icon handle so that when these icons are displayed * on a Mirrored DC, they end would be displayed normal. * * History: * 04-Feb-1998 samera Created \***************************************************************************/ BOOL WINAPI MirrorIcon(HICON* phiconSmall, HICON* phiconLarge) { HDC hdcScreen; HBITMAP hbm, hbmMask, hbmOld,hbmOldMask; BITMAP bm; HICON hicon[2] = {NULL,NULL}; HICON hiconNew[2] = {NULL,NULL}; ICONINFO ii ; int i; #ifdef WINNT #define IPIXELOFFSET 0 #else // !WINNT #define IPIXELOFFSET 2 #endif WINNT // // Synchronize access to global DCs now! // Allocate DCs if we didn't so far. // ENTERCRITICAL; if (!g_hdc && !g_hdcMask) { g_hdc = CreateCompatibleDC(NULL); if (g_hdc) { #ifndef UNIX #ifndef WINNT SetObjectOwner(g_hdc, HINST_THISDLL); #endif #endif /* !UNIX */ g_hdcMask = CreateCompatibleDC(NULL); if( g_hdcMask ) { #ifndef UNIX #ifndef WINNT SetObjectOwner(g_hdcMask, HINST_THISDLL); #endif #endif /* !UNIX */ SET_DC_RTL_MIRRORED(g_hdc); SET_DC_RTL_MIRRORED(g_hdcMask); } else { DeleteDC( g_hdc ); g_hdc = NULL; } } } if (phiconSmall) hicon[0] = *phiconSmall; if (phiconLarge) hicon[1] = *phiconLarge; // // Acquire the screen DC // hdcScreen = GetDC(NULL); if (g_hdc && g_hdcMask && hdcScreen) { for( i=0 ; i<(sizeof(hicon)/sizeof(HICON)) ; i++ ) { if( hicon[i] ) { if( GetIconInfo(hicon[i], &ii) && GetObject(ii.hbmColor, sizeof(BITMAP), &bm)) { // // I don't want these. // DeleteObject( ii.hbmMask ); DeleteObject( ii.hbmColor ); ii.hbmMask = ii.hbmColor = NULL; hbm = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight); hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL); hbmOld = (HBITMAP)SelectObject(g_hdc, hbm); hbmOldMask = (HBITMAP)SelectObject(g_hdcMask, hbmMask); DrawIconEx(g_hdc, IPIXELOFFSET, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0, NULL, DI_IMAGE); DrawIconEx(g_hdcMask, IPIXELOFFSET, 0, hicon[i], bm.bmWidth, bm.bmHeight, 0, NULL, DI_MASK); SelectObject(g_hdc, hbmOld); SelectObject(g_hdcMask, hbmOldMask); // // create the new mirrored icon, and delete bmps // ii.hbmMask = hbmMask; ii.hbmColor = hbm; hiconNew[i] = CreateIconIndirect(&ii); DeleteObject(hbm); DeleteObject(hbmMask); } } } } ReleaseDC(NULL, hdcScreen); // // Now we can reuse the global DCs // LEAVECRITICAL; // // Update icons if needed, and destroy old ones! // if (hicon[0] && hiconNew[0]) { *phiconSmall = hiconNew[0]; DestroyIcon(hicon[0]); } if (hicon[1] && hiconNew[1]) { *phiconLarge = hiconNew[1]; // // Don't delete twice // if (hicon[1] != hicon[0]) DestroyIcon(hicon[1]); } return TRUE; }