Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

profile.cpp

Go to the documentation of this file.
00001 /****************************************************************************** 00002 00003 Source File: ICC Profile.CPP 00004 00005 This implements the class we use to encapsulate everything we will ever care 00006 to know about a profile, including the classes we need to support 00007 associations and the like. 00008 00009 Copyright (c) 1996, 1997 by Microsoft Corporation. All Rights Reserved. 00010 00011 A Pretty Penny Enterprises Production 00012 00013 Change History: 00014 00015 10-31-96 A-RobKj (Pretty Penny Enterprises) began encapsulating it 00016 12-04-96 A-RobKj Added the CProfileArray and CAllDeviceList classes 00017 12-13-96 A-RobKj Modified for faster operation (more lazy evaluation, 00018 and common DLL-wide database for installation checks) 00019 Also moved CDeviceList derived classes to the header, so 00020 I can use them other places, as well... 00021 01-07-97 [email protected] Fixed CProfileArray::Empty- wasn't setting Next 00022 object pointer to NULL after deleting said object (Fixed GP fault). 00023 01-08-97 [email protected] Modified printer enumeration routine to only 00024 enumerate color models (uses Global utility function). 00025 00026 ******************************************************************************/ 00027 00028 #include "ICMUI.H" 00029 #include <shlobj.h> 00030 #include "shellext.h" 00031 #include "..\mscms\sti.h" 00032 00033 typedef HRESULT (__stdcall *PFNSTICREATEINSTANCE)(HINSTANCE, DWORD, PSTI*, LPDWORD); 00034 00035 TCHAR gszStiDll[] = __TEXT("sti.dll"); 00036 char gszStiCreateInstance[] = "StiCreateInstance"; 00037 00038 // Printer DeviceEnumeration method 00039 00040 void CPrinterList::Enumerate() { 00041 00042 #if !defined(_WIN95_) // CPrinterList::Enumetate() 00043 00044 // Enumerate all local printers 00045 00046 DWORD dwcNeeded, dwcReturned; 00047 EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwcNeeded, 00048 &dwcReturned); 00049 00050 union { 00051 PBYTE pBuff; 00052 PPRINTER_INFO_4 ppi4; 00053 }; 00054 00055 pBuff = new BYTE[dwcNeeded]; 00056 00057 while (pBuff && !EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, pBuff, 00058 dwcNeeded, &dwcNeeded, &dwcReturned) && 00059 GetLastError() == ERROR_MORE_DATA) { 00060 delete pBuff; 00061 pBuff = new BYTE[dwcNeeded]; 00062 } 00063 00064 if (pBuff) { 00065 00066 for (unsigned u = 0; u < dwcReturned; u++) 00067 if (CGlobals::ThisIsAColorPrinter(ppi4[u].pPrinterName)) { 00068 m_csaDeviceNames.Add(ppi4[u].pPrinterName); 00069 m_csaDisplayNames.Add(ppi4[u].pPrinterName); 00070 } 00071 00072 delete pBuff; 00073 } 00074 00075 // Now, enumerate all the connected printers 00076 00077 EnumPrinters(PRINTER_ENUM_CONNECTIONS, NULL, 4, NULL, 0, &dwcNeeded, 00078 &dwcReturned); 00079 00080 pBuff = new BYTE[dwcNeeded]; 00081 00082 while (pBuff && !EnumPrinters(PRINTER_ENUM_CONNECTIONS, NULL, 4, pBuff, 00083 dwcNeeded, &dwcNeeded, &dwcReturned) && 00084 GetLastError() == ERROR_MORE_DATA) { 00085 delete pBuff; 00086 pBuff = new BYTE[dwcNeeded]; 00087 } 00088 00089 if (!pBuff) 00090 return; 00091 00092 for (unsigned u = 0; u < dwcReturned; u++) 00093 if (CGlobals::ThisIsAColorPrinter(ppi4[u].pPrinterName)) { 00094 m_csaDeviceNames.Add(ppi4[u].pPrinterName); 00095 m_csaDisplayNames.Add(ppi4[u].pPrinterName); 00096 } 00097 00098 delete pBuff; 00099 00100 #else 00101 00102 // Enumerate all local printers 00103 00104 DWORD dwcNeeded, dwcReturned; 00105 EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, NULL, 0, &dwcNeeded, 00106 &dwcReturned); 00107 00108 union { 00109 PBYTE pBuff; 00110 PPRINTER_INFO_5 ppi5; 00111 }; 00112 00113 pBuff = new BYTE[dwcNeeded]; 00114 00115 while (pBuff && !EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, pBuff, 00116 dwcNeeded, &dwcNeeded, &dwcReturned) && 00117 GetLastError() == ERROR_MORE_DATA) { 00118 delete pBuff; 00119 pBuff = new BYTE[dwcNeeded]; 00120 } 00121 00122 if (pBuff) { 00123 00124 for (unsigned u = 0; u < dwcReturned; u++) { 00125 if (CGlobals::ThisIsAColorPrinter(ppi5[u].pPrinterName)) { 00126 m_csaDeviceNames.Add(ppi5[u].pPrinterName); 00127 m_csaDisplayNames.Add(ppi5[u].pPrinterName); 00128 } 00129 } 00130 00131 delete pBuff; 00132 } 00133 #endif 00134 } 00135 00136 // Printer Name Validity Check 00137 00138 BOOL CPrinterList::IsValidDeviceName(LPCTSTR lpstrRef) { 00139 00140 if (!lpstrRef) return FALSE; 00141 00142 if (!Count()) 00143 Enumerate(); 00144 00145 for (unsigned u = 0; u < Count(); u++) 00146 if (!lstrcmpi(m_csaDeviceNames[u], lpstrRef)) 00147 break; 00148 00149 return u < Count(); 00150 } 00151 00152 // Private monitor enumeration function- note this is ANSI only... 00153 00154 extern "C" BOOL WINAPI EnumerateMonitors(LPBYTE pBuffer, PDWORD pdwcbNeeded, 00155 PDWORD pdwcReturned); 00156 00157 // CMonitor class enumerator 00158 00159 void CMonitorList::Enumerate() { 00160 00161 ULONG ulSerialNumber = 1; 00162 ULONG ulDeviceIndex = 0; 00163 DISPLAY_DEVICE ddPriv; 00164 00165 ddPriv.cb = sizeof(ddPriv); 00166 00167 // Enumurate display adaptor on the system. 00168 00169 while (EnumDisplayDevices(NULL, ulDeviceIndex, &ddPriv, 0)) 00170 { 00171 ULONG ulMonitorIndex = 0; 00172 DISPLAY_DEVICE ddPrivMonitor; 00173 00174 ddPrivMonitor.cb = sizeof(ddPrivMonitor); 00175 00176 // then, enumurate monitor device, attached the display adaptor. 00177 00178 while (EnumDisplayDevices(ddPriv.DeviceName, ulMonitorIndex, &ddPrivMonitor, 0)) 00179 { 00180 TCHAR DisplayNameBuf[256]; // number: devicename - 256 is good enough. 00181 00182 // Insert PnP id as device name. 00183 00184 m_csaDeviceNames.Add(ddPrivMonitor.DeviceID); 00185 00186 // If this is primary display device, remember it. 00187 00188 if (ddPriv.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) 00189 { 00190 m_csPrimaryDeviceName = ddPrivMonitor.DeviceID; 00191 } 00192 00193 // Build display name. 00194 00195 wsprintf(DisplayNameBuf,TEXT("%d. %s"),ulSerialNumber,ddPrivMonitor.DeviceString); 00196 m_csaDisplayNames.Add(DisplayNameBuf); 00197 00198 ulMonitorIndex++; 00199 ulSerialNumber++; 00200 ddPrivMonitor.cb = sizeof(ddPrivMonitor); 00201 } 00202 00203 ulDeviceIndex++; 00204 ddPriv.cb = sizeof(ddPriv); 00205 } 00206 } 00207 00208 // Monitor Name Validity Check 00209 00210 BOOL CMonitorList::IsValidDeviceName(LPCTSTR lpstrRef) { 00211 00212 if (!lpstrRef) return FALSE; 00213 00214 if (!Count()) 00215 Enumerate(); 00216 00217 for (unsigned u = 0; u < Count(); u++) 00218 if (!lstrcmpi(m_csaDeviceNames[u], lpstrRef)) 00219 break; 00220 00221 return u < Count(); 00222 } 00223 00224 LPCSTR CMonitorList::DeviceNameToDisplayName(LPCTSTR lpstrRef) { 00225 00226 if (!lpstrRef) return NULL; 00227 00228 if (!Count()) 00229 Enumerate(); 00230 00231 for (unsigned u = 0; u < Count(); u++) 00232 if (!lstrcmpi(m_csaDeviceNames[u], lpstrRef)) 00233 return (LPCSTR)(m_csaDisplayNames[u]); 00234 00235 return NULL; 00236 } 00237 00238 // Scanner DeviceEnumeration method 00239 00240 void CScannerList::Enumerate() { 00241 00242 PFNSTICREATEINSTANCE pStiCreateInstance; 00243 PSTI pSti = NULL; 00244 PSTI_DEVICE_INFORMATION pDevInfo; 00245 PVOID pBuffer = NULL; 00246 HINSTANCE hModule; 00247 HRESULT hres; 00248 DWORD i, dwItemsReturned; 00249 #ifndef UNICODE 00250 char szName[256]; 00251 #endif 00252 00253 if (!(hModule = LoadLibrary(gszStiDll))) 00254 { 00255 _RPTF1(_CRT_WARN, "Error loading sti.dll: %d\n", 00256 GetLastError()); 00257 return; 00258 } 00259 00260 if (!(pStiCreateInstance = (PFNSTICREATEINSTANCE)GetProcAddress(hModule, gszStiCreateInstance))) 00261 { 00262 _RPTF0(_CRT_WARN, "Error getting proc StiCreateInstance\n"); 00263 goto EndEnumerate; 00264 } 00265 00266 hres = (*pStiCreateInstance)(GetModuleHandle(NULL), STI_VERSION, &pSti, NULL); 00267 00268 if (FAILED(hres)) 00269 { 00270 _RPTF1(_CRT_WARN, "Error creating sti instance: %d\n", hres); 00271 goto EndEnumerate; 00272 } 00273 00274 hres = pSti->GetDeviceList(0, 0, &dwItemsReturned, &pBuffer); 00275 00276 if (FAILED(hres) || !pBuffer) 00277 { 00278 _RPTF0(_CRT_WARN, "Error getting scanner devices\n"); 00279 goto EndEnumerate; 00280 } 00281 00282 pDevInfo = (PSTI_DEVICE_INFORMATION) pBuffer; 00283 00284 for (i=0; i<dwItemsReturned; i++, pDevInfo++) 00285 { 00286 #ifndef UNICODE 00287 DWORD dwLen; // length of Ansi string 00288 BOOL bUsedDefaultChar; 00289 00290 dwLen = (lstrlenW(pDevInfo->pszLocalName) + 1) * sizeof(char); 00291 00292 // 00293 // Convert Unicode name to Ansi 00294 // 00295 if (WideCharToMultiByte(CP_ACP, 0, pDevInfo->szDeviceInternalName, -1, szName, 00296 dwLen, NULL, &bUsedDefaultChar) && ! bUsedDefaultChar) 00297 { 00298 m_csaDeviceNames.Add(szName); 00299 } 00300 else 00301 { 00302 _RPTF0(_CRT_WARN, "Error converting internalName to Unicode name\n"); 00303 } 00304 00305 if (WideCharToMultiByte(CP_ACP, 0, pDevInfo->pszLocalName, -1, szName, 00306 dwLen, NULL, &bUsedDefaultChar) && ! bUsedDefaultChar) 00307 { 00308 m_csaDisplayNames.Add(szName); 00309 } 00310 else 00311 { 00312 _RPTF0(_CRT_WARN, "Error converting deviceName to Unicode name\n"); 00313 } 00314 00315 #else 00316 m_csaDeviceNames.Add(pDevInfo->szDeviceInternalName); 00317 m_csaDisplayNames.Add(pDevInfo->pszLocalName); 00318 #endif 00319 } 00320 00321 EndEnumerate: 00322 if (pBuffer) 00323 { 00324 LocalFree(pBuffer); 00325 } 00326 00327 if (pSti) 00328 { 00329 pSti->Release(); 00330 } 00331 00332 if (hModule) 00333 { 00334 FreeLibrary(hModule); 00335 } 00336 00337 return; 00338 } 00339 00340 // Scanner Name Validity Check 00341 00342 BOOL CScannerList::IsValidDeviceName(LPCTSTR lpstrRef) { 00343 00344 if (!lpstrRef) return FALSE; 00345 00346 if (!Count()) 00347 Enumerate(); 00348 00349 for (unsigned u = 0; u < Count(); u++) 00350 if (!lstrcmpi(m_csaDeviceNames[u], lpstrRef)) 00351 break; 00352 00353 return u < Count(); 00354 } 00355 00356 // CAllDeviceList class enumerator 00357 00358 void CAllDeviceList::Enumerate() { 00359 00360 CMonitorList cml; 00361 CPrinterList cpl; 00362 CScannerList csl; 00363 00364 cml.Enumerate(); 00365 cpl.Enumerate(); 00366 csl.Enumerate(); 00367 00368 for (unsigned u = 0; u < cpl.Count(); u++) { 00369 m_csaDeviceNames.Add(cpl.DeviceName(u)); 00370 m_csaDisplayNames.Add(cpl.DisplayName(u)); 00371 } 00372 00373 for (u = 0; u < cml.Count(); u++) { 00374 m_csaDeviceNames.Add(cml.DeviceName(u)); 00375 m_csaDisplayNames.Add(cml.DisplayName(u)); 00376 } 00377 00378 for (u = 0; u < csl.Count(); u++) { 00379 m_csaDeviceNames.Add(csl.DeviceName(u)); 00380 m_csaDisplayNames.Add(csl.DisplayName(u)); 00381 } 00382 } 00383 00384 // Device Name Validity Check 00385 00386 BOOL CAllDeviceList::IsValidDeviceName(LPCTSTR lpstrRef) { 00387 00388 if (!lpstrRef) return FALSE; 00389 00390 if (!Count()) 00391 Enumerate(); 00392 00393 for (unsigned u = 0; u < Count(); u++) 00394 if (!lstrcmpi(m_csaDeviceNames[u], lpstrRef)) 00395 break; 00396 00397 return u < Count(); 00398 } 00399 00400 // CProfile member functions 00401 00402 // The following static functions fills the appropriate array using the 00403 // profiles that match the search criteria goven. 00404 00405 void CProfile::Enumerate(ENUMTYPE& et, CStringArray& csaList) { 00406 00407 // Enumerate the existing profiles 00408 00409 DWORD dwBuffer =0, dwcProfiles; 00410 00411 csaList.Empty(); 00412 00413 EnumColorProfiles(NULL, &et, NULL, &dwBuffer, &dwcProfiles); 00414 00415 if (!dwBuffer) { 00416 _RPTF2(_CRT_WARN, 00417 "CProfile::Enumerate(String)- empty list- dwBuffer %d Error %d\n", 00418 dwBuffer, GetLastError()); 00419 return; 00420 } 00421 00422 union { 00423 PBYTE pbBuffer; 00424 PTSTR pstrBuffer; 00425 }; 00426 00427 pbBuffer = new BYTE[dwBuffer]; 00428 00429 if (pbBuffer) { 00430 00431 if (EnumColorProfiles(NULL, &et, pbBuffer, &dwBuffer, &dwcProfiles)) { 00432 for (PTSTR pstrMe = pstrBuffer; 00433 dwcProfiles--; 00434 pstrMe += 1 + lstrlen(pstrMe)) { 00435 _RPTF1(_CRT_WARN, "CProfile::Enumerate(String) %s found\n", 00436 pstrMe); 00437 csaList.Add(pstrMe); 00438 } 00439 } 00440 00441 delete pbBuffer; 00442 } 00443 } 00444 00445 void CProfile::Enumerate(ENUMTYPE& et, CStringArray& csaList, CStringArray& csaDesc) { 00446 00447 // Enumerate the existing profiles 00448 00449 DWORD dwBuffer =0, dwcProfiles; 00450 00451 csaList.Empty(); 00452 00453 EnumColorProfiles(NULL, &et, NULL, &dwBuffer, &dwcProfiles); 00454 00455 if (!dwBuffer) { 00456 _RPTF2(_CRT_WARN, 00457 "CProfile::Enumerate(String)- empty list- dwBuffer %d Error %d\n", 00458 dwBuffer, GetLastError()); 00459 return; 00460 } 00461 00462 union { 00463 PBYTE pbBuffer; 00464 PTSTR pstrBuffer; 00465 }; 00466 00467 pbBuffer = new BYTE[dwBuffer]; 00468 00469 if (pbBuffer) { 00470 00471 if (EnumColorProfiles(NULL, &et, pbBuffer, &dwBuffer, &dwcProfiles)) { 00472 for (PTSTR pstrMe = pstrBuffer; 00473 dwcProfiles--; 00474 pstrMe += 1 + lstrlen(pstrMe)) { 00475 _RPTF1(_CRT_WARN, "CProfile::Enumerate(String) %s found\n", 00476 pstrMe); 00477 00478 CProfile cp(pstrMe); 00479 00480 if (cp.IsValid()) { 00481 00482 CString csDescription = cp.TagContents('desc', 4); 00483 00484 if (csDescription.IsEmpty()) { 00485 csaDesc.Add(pstrMe); 00486 } else { 00487 csaDesc.Add((LPTSTR)csDescription); 00488 } 00489 00490 csaList.Add(pstrMe); 00491 } 00492 } 00493 } 00494 00495 delete pbBuffer; 00496 } 00497 } 00498 00499 void CProfile::Enumerate(ENUMTYPE& et, CProfileArray& cpaList) { 00500 00501 // Enumerate the existing profiles 00502 00503 DWORD dwBuffer = 0, dwcProfiles; 00504 00505 cpaList.Empty(); 00506 00507 EnumColorProfiles(NULL, &et, NULL, &dwBuffer, &dwcProfiles); 00508 00509 if (!dwBuffer) { 00510 _RPTF2(_CRT_WARN, 00511 "CProfile::Enumerate(Profile)- empty list- dwBuffer %d Error %d\n", 00512 dwBuffer, GetLastError()); 00513 return; 00514 } 00515 00516 union { 00517 PBYTE pbBuffer; 00518 PTSTR pstrBuffer; 00519 }; 00520 00521 pbBuffer = new BYTE[dwBuffer]; 00522 00523 if (pbBuffer) { 00524 00525 if (EnumColorProfiles(NULL, &et, pbBuffer, &dwBuffer, &dwcProfiles)) { 00526 for (PTSTR pstrMe = pstrBuffer; 00527 dwcProfiles--; 00528 pstrMe += 1 + lstrlen(pstrMe)) { 00529 _RPTF1(_CRT_WARN, "CProfile::Enumerate(Profile) %s added\n", 00530 pstrMe); 00531 cpaList.Add(pstrMe); 00532 } 00533 } 00534 00535 delete pbBuffer; 00536 } 00537 00538 } 00539 00540 // This retrieves the color directory name. Since it is a const, we whouldn't 00541 // be calling it too often... 00542 00543 const CString CProfile::ColorDirectory() { 00544 TCHAR acDirectory[MAX_PATH]; 00545 DWORD dwccDir = MAX_PATH; 00546 00547 GetColorDirectory(NULL, acDirectory, &dwccDir); 00548 00549 return acDirectory; 00550 } 00551 00552 // This checks for profile installation 00553 00554 void CProfile::InstallCheck() { 00555 00556 // Enumerate the existing profiles, so we can see if this one's been 00557 // installed, already. 00558 00559 ENUMTYPE et = {sizeof (ENUMTYPE), ENUM_TYPE_VERSION, 0, NULL}; 00560 00561 CStringArray csaWork; 00562 00563 Enumerate(et, csaWork); 00564 00565 for (unsigned u = 0; u < csaWork.Count(); u++) 00566 if (!lstrcmpi(csaWork[u].NameOnly(), m_csName.NameOnly())) 00567 break; 00568 00569 m_bIsInstalled = u < csaWork.Count(); 00570 m_bInstallChecked = TRUE; 00571 } 00572 00573 // This Checks for Associated Devices 00574 00575 void CProfile::AssociationCheck() { 00576 00577 m_bAssociationsChecked = TRUE; 00578 00579 // If the profile isn't installed, associations are moot... 00580 00581 if (!IsInstalled()) 00582 return; 00583 00584 // The final step is to build a list of associations 00585 00586 ENUMTYPE et = {sizeof (ENUMTYPE), ENUM_TYPE_VERSION, ET_DEVICENAME}; 00587 CStringArray csaWork; 00588 00589 for (unsigned u = 0; u < DeviceCount(); u++) { 00590 00591 et.pDeviceName = m_pcdlClass -> DeviceName(u); 00592 00593 Enumerate(et, csaWork); 00594 00595 // We track associations by index into the total device list... 00596 00597 for (unsigned uProfile = 0; uProfile < csaWork.Count(); uProfile++) 00598 if (!lstrcmpi(csaWork[uProfile].NameOnly(), m_csName.NameOnly())){ 00599 m_cuaAssociation.Add(u); // Found one! 00600 break; 00601 } 00602 } 00603 } 00604 00605 // This determines the device list of related class... 00606 00607 void CProfile::DeviceCheck() { 00608 00609 // Enumerate the available devices of this type in the csaDevice Array 00610 00611 m_pcdlClass -> Enumerate(); 00612 m_bDevicesChecked = TRUE; 00613 } 00614 00615 // Class constructor 00616 00617 CProfile::CProfile(LPCTSTR lpstrTarget) { 00618 00619 _ASSERTE(lpstrTarget && *lpstrTarget); 00620 00621 m_pcdlClass = NULL; 00622 00623 // First, let's make sure it's the real McCoy 00624 00625 PROFILE prof = { PROFILE_FILENAME, 00626 (LPVOID) lpstrTarget, 00627 (1 + lstrlen(lpstrTarget)) * sizeof(TCHAR)}; 00628 00629 m_hprof = OpenColorProfile(&prof, PROFILE_READ, 00630 FILE_SHARE_READ|FILE_SHARE_WRITE, 00631 OPEN_EXISTING); 00632 00633 if (!m_hprof) 00634 return; 00635 00636 if (!GetColorProfileHeader(m_hprof, &m_phThis)) { 00637 CloseColorProfile(m_hprof); 00638 m_hprof = NULL; 00639 return; 00640 } 00641 00642 m_csName = lpstrTarget; 00643 m_bInstallChecked = m_bDevicesChecked = m_bAssociationsChecked = FALSE; 00644 00645 // Init the DeviceList pointer, because it doesn't cost much... 00646 00647 switch (m_phThis.phClass) { 00648 case CLASS_PRINTER: 00649 00650 // Our device list is a printer list 00651 00652 m_pcdlClass = new CPrinterList; 00653 break; 00654 00655 case CLASS_SCANNER: 00656 00657 // Our device list is a scanner list 00658 00659 m_pcdlClass = new CScannerList; 00660 break; 00661 00662 00663 case CLASS_MONITOR: 00664 00665 // Our device list is a monitor list 00666 00667 #if 1 // ALLOW_MONITOR_PROFILE_TO_ANY_DEVICE 00668 m_pcdlClass = new CAllDeviceList; 00669 #else 00670 m_pcdlClass = new CMonitorList; 00671 #endif 00672 break; 00673 00674 case CLASS_COLORSPACE: 00675 00676 // List everything we can count 00677 00678 m_pcdlClass = new CAllDeviceList; 00679 break; 00680 00681 default: 00682 // Use the base device class (i.e., no devices of this type). 00683 m_pcdlClass = new CDeviceList; 00684 } 00685 } 00686 00687 // Destructor 00688 00689 CProfile::~CProfile() { 00690 if (m_hprof) 00691 CloseColorProfile(m_hprof); 00692 if (m_pcdlClass) 00693 delete m_pcdlClass; 00694 } 00695 00696 // Tag retrieval function 00697 00698 LPCSTR CProfile::TagContents(TAGTYPE tt, unsigned uOffset) { 00699 00700 DWORD dwcNeeded = sizeof m_acTag; 00701 BOOL bIgnore; 00702 00703 if (!GetColorProfileElement(m_hprof, tt, 8 + uOffset, &dwcNeeded, m_acTag, 00704 &bIgnore)) 00705 return NULL; // Nothing to copy! 00706 else 00707 return m_acTag; 00708 } 00709 00710 // Profile Installation function 00711 00712 BOOL CProfile::Install() { 00713 00714 if (!InstallColorProfile(NULL, m_csName)) { 00715 CGlobals::ReportEx(InstFailedWithName,NULL,FALSE, 00716 MB_OK|MB_ICONEXCLAMATION,1,m_csName.NameAndExtension()); 00717 return (FALSE); 00718 } else { 00719 m_bIsInstalled = TRUE; 00720 CGlobals::InvalidateList(); 00721 SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, (LPCTSTR) m_csName, NULL); 00722 00723 _RPTF1(_CRT_WARN, "CProfile::Install %s succeeded\n", 00724 (LPCSTR) m_csName); 00725 return (TRUE); 00726 } 00727 } 00728 00729 // Profile Uninstallation function 00730 00731 void CProfile::Uninstall(BOOL bDelete) { 00732 00733 while (AssociationCount()) { // Dissociate all uses 00734 Dissociate(DeviceName(m_cuaAssociation[0])); 00735 m_cuaAssociation.Remove(0); 00736 } 00737 00738 if (m_hprof) 00739 { 00740 CloseColorProfile(m_hprof); 00741 m_hprof = NULL; 00742 } 00743 00744 if (!UninstallColorProfile(NULL, m_csName.NameAndExtension(), bDelete)) { 00745 CGlobals::ReportEx(UninstFailedWithName,NULL,FALSE, 00746 MB_OK|MB_ICONEXCLAMATION,1,m_csName.NameAndExtension()); 00747 } else { 00748 m_bIsInstalled = FALSE; 00749 CGlobals::InvalidateList(); 00750 SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, (LPCTSTR) m_csName, NULL); 00751 00752 _RPTF1(_CRT_WARN, "CProfile::Uninstall %s succeeded\n", 00753 (LPCSTR) m_csName); 00754 } 00755 } 00756 00757 // Association 00758 00759 void CProfile::Associate(LPCTSTR lpstrDevice) { 00760 00761 // if the profile is not installed, install it first. 00762 00763 BOOL bInstalled = FALSE; 00764 00765 // Install profile, if not installed, yet. 00766 if (!IsInstalled()) { 00767 bInstalled = Install(); 00768 } else 00769 bInstalled = TRUE; 00770 00771 if (bInstalled) { 00772 if (!AssociateColorProfileWithDevice(NULL, m_csName.NameAndExtension(), 00773 lpstrDevice)) { 00774 CGlobals::ReportEx(AssocFailedWithName,NULL,FALSE,1, 00775 MB_OK|MB_ICONEXCLAMATION,m_csName.NameAndExtension()); 00776 } else 00777 _RPTF2(_CRT_WARN, "CProfile::Associate %s with %s succeeded\n", 00778 lpstrDevice, (LPCTSTR) m_csName.NameAndExtension()); 00779 } 00780 } 00781 00782 // Dissociation 00783 00784 void CProfile::Dissociate(LPCTSTR lpstrDevice) { 00785 if (!DisassociateColorProfileFromDevice(NULL, m_csName.NameAndExtension(), 00786 lpstrDevice)) { 00787 CGlobals::ReportEx(DisassocFailedWithName,NULL,FALSE,1, 00788 MB_OK|MB_ICONEXCLAMATION,m_csName.NameAndExtension()); 00789 } else 00790 _RPTF2(_CRT_WARN, "CProfile::Dissociate %s from %s succeeded\n", 00791 lpstrDevice, (LPCTSTR) m_csName.NameAndExtension()); 00792 } 00793 00794 // CProfileArray class- Same basic implementation, different base type. 00795 00796 CProfile *CProfileArray::Borrow() { 00797 CProfile *pcpReturn = m_aStore[0]; 00798 00799 memcpy((LPSTR) m_aStore, (LPSTR) (m_aStore + 1), 00800 (ChunkSize() - 1) * sizeof m_aStore[0]); 00801 00802 if (m_ucUsed > ChunkSize()) 00803 m_aStore[ChunkSize() - 1] = m_pcpaNext -> Borrow(); 00804 else 00805 m_aStore[ChunkSize() - 1] = (CProfile *) NULL; 00806 00807 m_ucUsed--; 00808 00809 if (m_ucUsed <= ChunkSize() && m_pcpaNext) { 00810 delete m_pcpaNext; 00811 m_pcpaNext = NULL; 00812 } 00813 00814 return pcpReturn; 00815 } 00816 00817 CProfileArray::CProfileArray() { 00818 m_ucUsed = 0; 00819 m_pcpaNext = NULL; 00820 memset(m_aStore, 0, sizeof m_aStore); 00821 } 00822 00823 CProfileArray::~CProfileArray() { 00824 Empty(); 00825 } 00826 00827 void CProfileArray::Empty() { 00828 if (!m_ucUsed) return; 00829 00830 if (m_pcpaNext) { 00831 delete m_pcpaNext; 00832 m_pcpaNext = NULL; 00833 m_ucUsed = ChunkSize(); 00834 } 00835 00836 while (m_ucUsed--) 00837 delete m_aStore[m_ucUsed]; 00838 00839 m_ucUsed = 0; 00840 memset(m_aStore, 0, sizeof m_aStore); 00841 } 00842 00843 // Add an item 00844 void CProfileArray::Add(LPCTSTR lpstrNew) { 00845 _ASSERTE(lpstrNew && *lpstrNew); 00846 00847 if (m_ucUsed < ChunkSize()) { 00848 m_aStore[m_ucUsed++] = new CProfile(lpstrNew); 00849 return; 00850 } 00851 00852 // Not enough space! Add another record, if there isn't one 00853 00854 if (!m_pcpaNext) 00855 m_pcpaNext = new CProfileArray; 00856 00857 // Add the profile to the next array (recursive call!) 00858 00859 m_pcpaNext -> Add(lpstrNew); 00860 m_ucUsed++; 00861 } 00862 00863 CProfile *CProfileArray::operator [](unsigned u) const { 00864 return u < ChunkSize() ? 00865 m_aStore[u] : m_pcpaNext -> operator[](u - ChunkSize()); 00866 } 00867 00868 void CProfileArray::Remove(unsigned u) { 00869 00870 if (u > m_ucUsed) 00871 return; 00872 00873 if (u >= ChunkSize()) { 00874 m_pcpaNext -> Remove(u - ChunkSize()); 00875 return; 00876 } 00877 00878 delete m_aStore[u]; 00879 00880 memmove((LPSTR) (m_aStore + u), (LPSTR) (m_aStore + u + 1), 00881 (ChunkSize() - (u + 1)) * sizeof m_aStore[0]); 00882 00883 if (m_ucUsed > ChunkSize()) 00884 m_aStore[ChunkSize() - 1] = m_pcpaNext -> Borrow(); 00885 else 00886 m_aStore[ChunkSize() - 1] = (CProfile *) NULL; 00887 00888 m_ucUsed--; 00889 00890 if (m_ucUsed <= ChunkSize() && m_pcpaNext) { 00891 delete m_pcpaNext; 00892 m_pcpaNext = NULL; 00893 } 00894 }

Generated on Sat May 15 19:41:29 2004 for test by doxygen 1.3.7