[SHLWAPI] Implement SHAreIconsEqual
[reactos.git] / dll / win32 / shlwapi / rosordinal.c
1 /*
2 * PROJECT: ReactOS Shell
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Misc shell helper functions
5 * COPYRIGHT: Copyright 2015 Giannis Adamopoulos
6 */
7
8 #include "precomp.h"
9
10 /* http://undoc.airesoft.co.uk/shlwapi.dll/SHForwardContextMenuMsg.php */
11 HRESULT WINAPI SHForwardContextMenuMsg(IUnknown* pUnk, UINT uMsg, WPARAM wParam,
12 LPARAM lParam, LRESULT* pResult, BOOL useIContextMenu2)
13 {
14 HRESULT hr;
15 IContextMenu3* pcmenu3;
16 IContextMenu2* pcmenu2;
17
18 /* First try to use the IContextMenu3 interface */
19 hr = IUnknown_QueryInterface(pUnk, &IID_IContextMenu3, (void**)&pcmenu3);
20 if (SUCCEEDED(hr))
21 {
22 hr = IContextMenu3_HandleMenuMsg2(pcmenu3, uMsg, wParam, lParam, pResult);
23 IContextMenu3_Release(pcmenu3);
24 return hr;
25 }
26
27 /* Return failure if we can't use the IContextMenu2 interface */
28 if(!useIContextMenu2)
29 return hr;
30
31 /* Now try to use the IContextMenu2 interface */
32 hr = IUnknown_QueryInterface(pUnk, &IID_IContextMenu2, (void**)&pcmenu2);
33 if (FAILED(hr))
34 return hr;
35
36 hr = IContextMenu2_HandleMenuMsg(pcmenu2, uMsg, wParam, lParam);
37 IContextMenu2_Release(pcmenu2);
38 return hr;
39 }
40
41 /* http://undoc.airesoft.co.uk/shlwapi.dll/SHAreIconsEqual.php */
42
43 BOOL WINAPI SHAreIconsEqual(HICON hIcon1, HICON hIcon2)
44 {
45 ICONINFO iconInfo1, iconInfo2;
46 BITMAP bm1, bm2;
47 BOOL bSame = FALSE;
48
49 if (!hIcon1 || !hIcon2)
50 return FALSE;
51
52 if (!GetIconInfo(hIcon1, &iconInfo1))
53 return FALSE;
54
55 if (!GetIconInfo(hIcon2, &iconInfo2))
56 {
57 DeleteObject(iconInfo1.hbmColor);
58 DeleteObject(iconInfo1.hbmMask);
59 return FALSE;
60 }
61
62 GetObjectW(iconInfo1.hbmColor, sizeof(bm1), &bm1);
63 GetObjectW(iconInfo2.hbmColor, sizeof(bm2), &bm2);
64
65 if (bm1.bmWidth == bm2.bmWidth && bm1.bmHeight == bm2.bmHeight)
66 {
67 BITMAPINFO bmi = { { sizeof(bmi), bm1.bmWidth, bm1.bmHeight, 1, 32 } };
68 HDC hdc = GetDC(0);
69 SIZE_T size = bm1.bmWidth * bm1.bmHeight * 4;
70 BYTE *data1, *data2;
71
72 data1 = HeapAlloc(GetProcessHeap(), 0, size);
73 data2 = HeapAlloc(GetProcessHeap(), 0, size);
74
75 if (data1 && data2)
76 {
77 if (GetDIBits(hdc, iconInfo1.hbmColor, 0, bm1.bmHeight, data1, &bmi, DIB_RGB_COLORS) &&
78 GetDIBits(hdc, iconInfo2.hbmColor, 0, bm2.bmHeight, data2, &bmi, DIB_RGB_COLORS))
79 {
80 bSame = memcmp(data1, data2, size) == 0;
81 }
82 }
83 HeapFree(GetProcessHeap(), 0, data1);
84 HeapFree(GetProcessHeap(), 0, data2);
85
86 ReleaseDC(NULL, hdc);
87 }
88
89 DeleteObject(iconInfo1.hbmColor);
90 DeleteObject(iconInfo1.hbmMask);
91
92 DeleteObject(iconInfo2.hbmColor);
93 DeleteObject(iconInfo2.hbmMask);
94
95 return bSame;
96 }