1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2014 - TortoiseGit
4 // Copyright (C) 2011-2012 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "TaskbarUUID.h"
24 #include "CmdLineParser.h"
27 #include "SmartHandle.h"
31 #define APPID (_T("TGIT.TGIT.1"))
33 void SetTaskIDPerUUID()
35 typedef HRESULT STDAPICALLTYPE
SetCurrentProcessExplicitAppUserModelIDFN(PCWSTR AppID
);
36 CAutoLibrary hShell
= AtlLoadSystemLibraryUsingFullPath(_T("shell32.dll"));
39 SetCurrentProcessExplicitAppUserModelIDFN
*pfnSetCurrentProcessExplicitAppUserModelID
= (SetCurrentProcessExplicitAppUserModelIDFN
*)GetProcAddress(hShell
, "SetCurrentProcessExplicitAppUserModelID");
40 if (pfnSetCurrentProcessExplicitAppUserModelID
)
42 std::wstring id
= GetTaskIDPerUUID();
43 pfnSetCurrentProcessExplicitAppUserModelID(id
.c_str());
48 std::wstring
GetTaskIDPerUUID(LPCTSTR uuid
/*= NULL */)
50 CRegStdDWORD r
= CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3);
51 std::wstring id
= APPID
;
52 if ((r
< 2)||(r
== 3))
54 wchar_t buf
[MAX_PATH
] = {0};
55 GetModuleFileName(NULL
, buf
, MAX_PATH
);
57 n
= n
.substr(n
.find_last_of('\\'));
69 CCmdLineParser
parser(GetCommandLine());
70 if (parser
.HasVal(L
"groupuuid"))
72 id
+= parser
.GetVal(L
"groupuuid");
80 extern CString g_sGroupingUUID
;
81 extern CString g_sGroupingIcon
;
82 extern bool g_bGroupingRemoveIcon
;
85 void SetUUIDOverlayIcon( HWND hWnd
)
87 if (CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3))
89 if (CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepoOverlay"), TRUE
))
93 bool bRemoveicon
= false;
95 uuid
= g_sGroupingUUID
;
96 sicon
= g_sGroupingIcon
;
97 bRemoveicon
= g_bGroupingRemoveIcon
;
99 CCmdLineParser
parser(GetCommandLine());
100 if (parser
.HasVal(L
"groupuuid"))
101 uuid
= parser
.GetVal(L
"groupuuid");
105 ITaskbarList3
* pTaskbarInterface
= NULL
;
106 HRESULT hr
= CoCreateInstance(CLSID_TaskbarList
, NULL
, CLSCTX_INPROC_SERVER
, IID_ITaskbarList3
, reinterpret_cast<void**> (&(pTaskbarInterface
)));
110 int foundUUIDIndex
= 0;
113 wchar_t buf
[MAX_PATH
] = {0};
114 swprintf_s(buf
, _countof(buf
), L
"%s%d", L
"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\", foundUUIDIndex
);
115 CRegStdString r
= CRegStdString(buf
);
119 r
= uuid
+ (sicon
.empty() ? L
"" : (L
";" + sicon
));
122 size_t sep
= sr
.find(L
';');
123 std::wstring olduuid
= sep
!= std::wstring::npos
? sr
.substr(0, sep
) : sr
;
124 if (olduuid
.compare(uuid
) == 0)
127 r
= uuid
; // reset icon path in registry
128 else if (!sicon
.empty())
129 r
= uuid
+ (sicon
.empty() ? L
"" : (L
";" + sicon
));
131 sicon
= sep
!= std::wstring::npos
? sr
.substr(sep
+ 1) : L
"";
135 } while (foundUUIDIndex
< 20);
136 if (foundUUIDIndex
>= 20)
138 CRegStdString r
= CRegStdString(L
"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\1");
142 HICON icon
= nullptr;
145 if (sicon
.size() >=4 && !_wcsicmp(sicon
.substr(sicon
.size() - 4).c_str(), L
".ico"))
147 icon
= (HICON
)::LoadImage(NULL
, sicon
.c_str(), IMAGE_ICON
, 16, 16, LR_LOADFROMFILE
| LR_SHARED
);
151 ULONG_PTR gdiplusToken
= 0;
152 Gdiplus::GdiplusStartupInput gdiplusStartupInput
;
153 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, nullptr);
156 Gdiplus::Bitmap
*pBitmap
= new Gdiplus::Bitmap(sicon
.c_str(), FALSE
);
157 if (pBitmap
->GetLastStatus() == Gdiplus::Status::Ok
)
158 pBitmap
->GetHICON(&icon
);
160 Gdiplus::GdiplusShutdown(gdiplusToken
);
167 DWORD colors
[6] = {0x80FF0000, 0x80FFFF00, 0x8000FF00, 0x800000FF, 0x80000000, 0x8000FFFF};
169 // AND mask - monochrome - determines which pixels get drawn
171 for( int i
=0; i
<32; i
++ )
176 // XOR mask - 32bpp ARGB - determines the pixel values
178 for( int i
=0; i
<256; i
++ )
180 XOR
[i
] = colors
[foundUUIDIndex
% 6];
183 icon
= ::CreateIcon(NULL
,16,16,1,32,AND
,(BYTE
*)XOR
);
185 pTaskbarInterface
->SetOverlayIcon(hWnd
, icon
, uuid
.c_str());
186 pTaskbarInterface
->Release();