1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_shell.hxx" 26 #include "internal/config.hxx" 27 #include "internal/global.hxx" 28 29 #ifndef PROPSEETS_HXX_INCLUDED 30 #include "internal/propsheets.hxx" 31 #endif 32 #include "internal/utilities.hxx" 33 #include "internal/resource.h" 34 #include "listviewbuilder.hxx" 35 36 #if defined _MSC_VER 37 #pragma warning(push, 1) 38 #endif 39 #include <shellapi.h> 40 #if defined _MSC_VER 41 #pragma warning(pop) 42 #endif 43 44 #include <string> 45 #include <vector> 46 #include <utility> 47 #include <strsafe.h> 48 49 50 /*--------------------------------------------- 51 INFO - INFO - INFO - INFO - INFO - INFO 52 53 See MSDN "Using Windows XP Visual Styles" 54 for hints how to enable the new common 55 control library for our property sheet. 56 57 INFO - INFO - INFO - INFO - INFO - INFO 58 ----------------------------------------------*/ 59 60 //----------------------------- 61 // 62 //----------------------------- 63 64 CPropertySheet::CPropertySheet(long RefCnt) : 65 m_RefCnt(RefCnt) 66 { 67 OutputDebugStringFormat("CPropertySheet::CTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); 68 InterlockedIncrement(&g_DllRefCnt); 69 } 70 71 //----------------------------- 72 // 73 //----------------------------- 74 75 CPropertySheet::~CPropertySheet() 76 { 77 OutputDebugStringFormat("CPropertySheet::DTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); 78 InterlockedDecrement(&g_DllRefCnt); 79 } 80 81 //----------------------------- 82 // IUnknown methods 83 //----------------------------- 84 85 HRESULT STDMETHODCALLTYPE CPropertySheet::QueryInterface( 86 REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) 87 { 88 *ppvObject = 0; 89 90 IUnknown* pUnk = 0; 91 if (IID_IUnknown == riid || IID_IShellExtInit == riid) 92 { 93 pUnk = static_cast<IShellExtInit*>(this); 94 pUnk->AddRef(); 95 *ppvObject = pUnk; 96 return S_OK; 97 } 98 else if (IID_IShellPropSheetExt == riid) 99 { 100 pUnk = static_cast<IShellPropSheetExt*>(this); 101 pUnk->AddRef(); 102 *ppvObject = pUnk; 103 return S_OK; 104 } 105 106 return E_NOINTERFACE; 107 } 108 109 //----------------------------- 110 // 111 //----------------------------- 112 113 ULONG STDMETHODCALLTYPE CPropertySheet::AddRef(void) 114 { 115 OutputDebugStringFormat("CPropertySheet::AddRef [%d]", m_RefCnt ); 116 return InterlockedIncrement(&m_RefCnt); 117 } 118 119 //----------------------------- 120 // 121 //----------------------------- 122 123 ULONG STDMETHODCALLTYPE CPropertySheet::Release(void) 124 { 125 OutputDebugStringFormat("CPropertySheet::Release [%d]", m_RefCnt ); 126 long refcnt = InterlockedDecrement(&m_RefCnt); 127 128 if (0 == refcnt) 129 delete this; 130 131 return refcnt; 132 } 133 134 //----------------------------- 135 // IShellExtInit 136 //----------------------------- 137 138 HRESULT STDMETHODCALLTYPE CPropertySheet::Initialize( 139 LPCITEMIDLIST /*pidlFolder*/, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) 140 { 141 InitCommonControls(); 142 143 STGMEDIUM medium; 144 FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; 145 146 HRESULT hr = lpdobj->GetData(&fe, &medium); 147 148 // save the file name 149 if (SUCCEEDED(hr) && 150 (1 == DragQueryFileA( 151 reinterpret_cast<HDROP>(medium.hGlobal), 152 0xFFFFFFFF, 153 NULL, 154 0))) 155 { 156 UINT size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 0, 0, 0 ); 157 if ( size != 0 ) 158 { 159 TCHAR * buffer = new TCHAR[ size + 1 ]; 160 UINT result_size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 161 0, buffer, size + 1 ); 162 if ( result_size != 0 ) 163 { 164 std::wstring fname = getShortPathName( buffer ); 165 std::string fnameA = WStringToString( fname ); 166 ZeroMemory( m_szFileName, sizeof( m_szFileName ) ); 167 strncpy( m_szFileName, fnameA.c_str(), ( sizeof( m_szFileName ) - 1 ) ); 168 hr = S_OK; 169 } 170 else 171 hr = E_INVALIDARG; 172 delete [] buffer; 173 } 174 else 175 hr = E_INVALIDARG; 176 } 177 else 178 hr = E_INVALIDARG; 179 180 ReleaseStgMedium(&medium); 181 182 return hr; 183 } 184 185 //----------------------------- 186 // IShellPropSheetExt 187 //----------------------------- 188 189 HRESULT STDMETHODCALLTYPE CPropertySheet::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) 190 { 191 // Get OS version (we don't need the summary page on Windows Vista or later) 192 OSVERSIONINFO sInfoOS; 193 194 ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) ); 195 sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); 196 GetVersionEx( &sInfoOS ); 197 bool bIsVistaOrLater = (sInfoOS.dwMajorVersion >= 6); 198 199 std::wstring proppage_header; 200 201 PROPSHEETPAGE psp; 202 ZeroMemory(&psp, sizeof(PROPSHEETPAGEA)); 203 204 // add the summary property page 205 psp.dwSize = sizeof(PROPSHEETPAGE); 206 psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USECALLBACK; 207 psp.hInstance = GetModuleHandle(MODULE_NAME); 208 psp.lParam = reinterpret_cast<LPARAM>(this); 209 psp.pfnCallback = reinterpret_cast<LPFNPSPCALLBACK>(CPropertySheet::PropPageSummaryCallback); 210 211 HPROPSHEETPAGE hPage = NULL; 212 213 if ( !bIsVistaOrLater ) 214 { 215 proppage_header = GetResString(IDS_PROPPAGE_SUMMARY_TITLE); 216 217 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SUMMARY); 218 psp.pszTitle = proppage_header.c_str(); 219 psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageSummaryProc); 220 221 hPage = CreatePropertySheetPage(&psp); 222 223 // keep this instance alive, will be released when the 224 // the page is about to be destroyed in the callback function 225 226 if (hPage) 227 { 228 if (lpfnAddPage(hPage, lParam)) 229 AddRef(); 230 else 231 DestroyPropertySheetPage(hPage); 232 } 233 } 234 235 // add the statistics property page 236 proppage_header = GetResString(IDS_PROPPAGE_STATISTICS_TITLE); 237 238 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_STATISTICS); 239 psp.pszTitle = proppage_header.c_str(); 240 psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageStatisticsProc); 241 242 hPage = CreatePropertySheetPage(&psp); 243 244 if (hPage) 245 { 246 if (lpfnAddPage(hPage, lParam)) 247 AddRef(); 248 else 249 DestroyPropertySheetPage(hPage); 250 } 251 252 // always return success else 253 // no property sheet will be 254 // displayed at all 255 return NOERROR; 256 } 257 258 //----------------------------- 259 // 260 //----------------------------- 261 262 HRESULT STDMETHODCALLTYPE CPropertySheet::ReplacePage( 263 UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/) 264 { 265 return E_NOTIMPL; 266 } 267 268 //----------------------------- 269 // 270 //----------------------------- 271 272 UINT CALLBACK CPropertySheet::PropPageSummaryCallback( 273 HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp) 274 { 275 CPropertySheet* pImpl = 276 reinterpret_cast<CPropertySheet*>(ppsp->lParam); 277 278 // release this instance, acquired 279 // in the AddPages method 280 if (PSPCB_RELEASE == uMsg) 281 { 282 pImpl->Release(); 283 } 284 285 return TRUE; 286 } 287 288 289 //----------------------------- 290 // 291 //----------------------------- 292 293 BOOL CALLBACK CPropertySheet::PropPageSummaryProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) 294 { 295 switch (uiMsg) 296 { 297 case WM_INITDIALOG: 298 { 299 LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); 300 CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); 301 pImpl->InitPropPageSummary(hwnd, psp); 302 return TRUE; 303 } 304 } 305 306 return FALSE; 307 } 308 309 //----------------------------- 310 // 311 //----------------------------- 312 313 BOOL CALLBACK CPropertySheet::PropPageStatisticsProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) 314 { 315 switch (uiMsg) 316 { 317 case WM_INITDIALOG: 318 { 319 LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); 320 CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); 321 pImpl->InitPropPageStatistics(hwnd, psp); 322 return TRUE; 323 } 324 } 325 326 return FALSE; 327 } 328 329 //################################## 330 void CPropertySheet::InitPropPageSummary(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) 331 { 332 try 333 { 334 CMetaInfoReader metaInfo(m_szFileName); 335 336 SetWindowText(GetDlgItem(hwnd,IDC_TITLE), metaInfo.getTagData( META_INFO_TITLE ).c_str() ); 337 SetWindowText(GetDlgItem(hwnd,IDC_AUTHOR), metaInfo.getTagData( META_INFO_AUTHOR ).c_str() ); 338 SetWindowText(GetDlgItem(hwnd,IDC_SUBJECT), metaInfo.getTagData( META_INFO_SUBJECT ).c_str() ); 339 SetWindowText(GetDlgItem(hwnd,IDC_KEYWORDS), metaInfo.getTagData( META_INFO_KEYWORDS ).c_str() ); 340 341 // comments read from meta.xml use "\n" for return, but this will not displayable in Edit control, add 342 // "\r" before "\n" to form "\r\n" in order to display return in Edit control. 343 std::wstring tempStr = metaInfo.getTagData( META_INFO_DESCRIPTION ).c_str(); 344 std::wstring::size_type itor = tempStr.find ( L"\n" , 0 ); 345 while (itor != std::wstring::npos) 346 { 347 tempStr.insert(itor, L"\r"); 348 itor = tempStr.find(L"\n", itor + 2); 349 } 350 SetWindowText(GetDlgItem(hwnd,IDC_COMMENTS), tempStr.c_str()); 351 } 352 catch (const std::exception&) 353 { 354 } 355 } 356 357 //--------------------------------- 358 /** 359 */ 360 void CPropertySheet::InitPropPageStatistics(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) 361 { 362 try 363 { 364 CMetaInfoReader metaInfo(m_szFileName); 365 366 document_statistic_reader_ptr doc_stat_reader = create_document_statistic_reader(m_szFileName, &metaInfo); 367 368 statistic_group_list_t sgl; 369 doc_stat_reader->read(&sgl); 370 371 list_view_builder_ptr lv_builder = create_list_view_builder( 372 GetDlgItem(hwnd, IDC_STATISTICSLIST), 373 GetResString(IDS_PROPERTY), 374 GetResString(IDS_PROPERTY_VALUE)); 375 376 lv_builder->build(sgl); 377 } 378 catch (const std::exception&) 379 { 380 } 381 } 382